From 113bb2371fe37e151ff480e18503acddd13a0fdd Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 18 Sep 2012 12:23:30 -0700 Subject: [PATCH 01/57] 2012:0918 21:20 - Added files to compile Refprop library on Linux. The shared library librefprop.so can be accessed from both C++ and Fortran. IMPORTANT: The wrapper classes for Modelica do not work, yet. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 161 ++ .../Version 0.5_linux/doc/Doxyfile | 1749 +++++++++++++++++ .../Version 0.5_linux/refprop_wrapper.cpp | 812 ++++++++ .../Version 0.5_linux/refprop_wrapper.h | 44 + .../Version 0.5_linux/refpropwrappertest.cpp | 71 + .../Version 0.5_linux/src/PASS_FTN_LIN.FOR | 1364 +++++++++++++ .../Version 0.5_linux/src/librefprop.h | 331 ++++ .../Version 0.5_linux/src/refprop-ftn.cpp | 233 +++ package.mo | 4 +- 9 files changed, 4767 insertions(+), 2 deletions(-) create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/Makefile create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.h create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/librefprop.h create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile new file mode 100644 index 0000000..4fb8093 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -0,0 +1,161 @@ +# ============================================================================ +# Name : Makefile +# Author : Jorrit Wronski (jowr@mek.dtu.dk) +# Version : 0.2 +# Copyright : Use and modify at your own risk. +# Description : Makefile for Refprop from Fortran and C++ tests. +# ============================================================================ + +# used for the output +BINDIR =. +THENAME =refprop + +THEWRAPPER =refprop_wrapper +THETEST =refpropwrappertest + +########################################################### +# Change these lines if you are using a different Fortran +# compiler or if you would like to use other flags. +########################################################### +FC =gfortran +FFLAGS =-Wall -ff2c -pedantic -ffloat-store# -fbounds-check +FLINKFLAGS =$(FFLAGS) + +########################################################### +# Change these lines if you are using a different C++ +# compiler or if you would like to use other flags. +########################################################### +CPPC =g++ +CPPFLAGS =-O2 -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 + +########################################################### +# Change these lines if you have other needs regarding +# the library file. +########################################################### +LIBFLAGS =-rdynamic -fPIC -shared +LIBDIR =/home/jowr/Documents/Fluids/refprop/v9.0 +LIBRARY =lib$(THENAME) +LIBFILE =PASS_FTN_LIN +DYNAMICLIBRARYEXTENSION =.so +STATICLIBRARYEXTENSION =.a +#ar -cvq $(LIBRARY)$(STATICLIBRARYEXTENSION) $(OBJECTFILES) +HEADERFILE =lib$(THENAME) +HEADEREXTENSION =.h +### List of files to compile +LIBOBJECTFILES = \ + $(LIBDIR)/fortran/SETUP.o \ + $(LIBDIR)/fortran/CORE_ANC.o \ + $(LIBDIR)/fortran/CORE_BWR.o \ + $(LIBDIR)/fortran/CORE_CPP.o \ + $(LIBDIR)/fortran/CORE_DE.o \ + $(LIBDIR)/fortran/CORE_ECS.o \ + $(LIBDIR)/fortran/CORE_FEQ.o \ + $(LIBDIR)/fortran/CORE_MLT.o \ + $(LIBDIR)/fortran/CORE_PH0.o \ + $(LIBDIR)/fortran/CORE_QUI.o \ + $(LIBDIR)/fortran/CORE_STN.o \ + $(LIBDIR)/fortran/CORE_PR.o \ + $(LIBDIR)/fortran/FLASH2.o \ + $(LIBDIR)/fortran/FLSH_SUB.o \ + $(LIBDIR)/fortran/IDEALGAS.o \ + $(LIBDIR)/fortran/MIX_AGA8.o \ + $(LIBDIR)/fortran/MIX_HMX.o \ + $(LIBDIR)/fortran/PROP_SUB.o \ + $(LIBDIR)/fortran/REALGAS.o \ + $(LIBDIR)/fortran/SAT_SUB.o \ + $(LIBDIR)/fortran/SETUP2.o \ + $(LIBDIR)/fortran/TRNS_ECS.o \ + $(LIBDIR)/fortran/TRNS_TCX.o \ + $(LIBDIR)/fortran/TRNS_VIS.o \ + $(LIBDIR)/fortran/TRNSP.o \ + $(LIBDIR)/fortran/UTILITY.o + + +########################################################### +# Compile the wrapper class and its tests. +########################################################### +.PHONY : wrapper +wrapper : $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) +$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) + +.PHONY : test +test : $(THETEST) +$(THETEST) : $(THETEST).o $(THEWRAPPER).o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + +########################################################### +# Compile the Fortran sources into a library file that can +# be used as a shared object. +########################################################### +.PHONY : libinstall +libinstall : library libheader + ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) + ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : libheader +libheader : $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) +$(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION): src/$(HEADERFILE)$(HEADEREXTENSION) + cp src/$(HEADERFILE)$(HEADEREXTENSION) $(LIBDIR) + +.PHONY : library +library : $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) +$(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION): src/$(LIBFILE).o $(LIBOBJECTFILES) + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) src/$(LIBFILE).o $(LIBOBJECTFILES) + +$(LIBDIR)/fortran/%.o: $(LIBDIR)/fortran/%.FOR + $(FC) $(FFLAGS) -o $(LIBDIR)/fortran/$*.o -c $< + +########################################################### +# General rulesets for compilation. +########################################################### +src/%.o : src/%.FOR + $(FC) $(FFLAGS) -o src/$*.o -c $< + +src/%.o : src/%.cpp + $(CPPC) $(CPPFLAGS) -o src/$*.o -c $< + +%.o : %.FOR + $(FC) $(FFLAGS) -o $*.o -c $< + +%.o : %.cpp + $(CPPC) $(CPPFLAGS) -o $*.o -c $< + +.PHONY: clean +clean: + $(RM) **.o **.so **.mod $(BINDIR)/RP-ftn + +########################################################### +# Compile a simple example to illustrate the connection +# between C++ and Fortran as well as the usage of the +# created library with Fortran sources. +########################################################### +.PHONY : RP-ftn +RP-ftn : $(BINDIR)/RP-ftn +$(BINDIR)/RP-ftn : src/refprop-ftn.cpp libheader library + $(CPPC) $(CPPFLAGS) -o src/refprop-ftn.o -c src/refprop-ftn.cpp + $(FC) $(FLINKFLAGS) -o $(BINDIR)/RP-ftn src/refprop-ftn.o -l$(THENAME) + +.PHONY : f2f +f2f : $(BINDIR)/f2f +$(BINDIR)/f2f : example/ex-mix.for $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(FC) $(FFLAGS) -o example/ex-mix.o -c example/ex-mix.for + $(FC) $(FLINKFLAGS) -o $(BINDIR)/f2f example/ex-mix.o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : cpp2f +cpp2f : $(BINDIR)/cpp2f +$(BINDIR)/cpp2f : example/cpp2f.cpp example/easy_f.for + $(FC) $(FFLAGS) -o example/easy_f.o -c example/easy_f.for + $(CPPC) $(CPPFLAGS) -o example/cpp2f.o -c example/cpp2f.cpp + $(FC) $(FLINKFLAGS) -o $(BINDIR)/cpp2f example/cpp2f.o example/easy_f.o + +########################################################### +# Create the documentation from annotations in the source +# files with DOXYGEN, a configuration file is needed. +########################################################### +.PHONY : doc +doc : doc/Doxyfile + doxygen doc/Doxyfile + cd doc/latex ; \ + make all + \ No newline at end of file diff --git a/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile b/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile new file mode 100644 index 0000000..7ec9879 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile @@ -0,0 +1,1749 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Refprop2Modelica - Linux" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.2 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Porting Henning Francke's Refprop2Modelica to Dymola on Linux" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = /mnt/crypt/Software/modelica/Dymola/dymola-icon-small.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = "/home/jowr/Documents/Modelica_Libraries/REFPROP2Modelica/_REFPROP-Wrapper/Version 0.5_linux/doc" + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = "/home/jowr/Documents/Modelica_Libraries/REFPROP2Modelica/_REFPROP-Wrapper/Version 0.5_linux" + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp new file mode 100644 index 0000000..d2a7c92 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp @@ -0,0 +1,812 @@ +/* + wrapper code for a static library containing functions from the dynamic library refprop.dll + to be used from Modelica + + This file is released under the Modelica License 2. + + Coded in 2010 by + Henning Francke + francke@gfz-potsdam.de + + Helmholtz Centre Potsdam + GFZ German Research Centre for Geosciences + Telegrafenberg, D-14473 Potsdam + + Modified for Linux in 2012 by + Jorrit Wronski (jowr@mek.dtu.dk) + DTU Mechanical Engineering + + needs + librefprop.h - header for librefprop.so, based on examples + refprop_wrapper.h - header for static REFPROP_wrapper.a, also needed by Dymola + + Use the provided makefile to install the library file from source. +*/ + +//#define DEBUGMODE 1 + +//#include +#include +#include +#include +#include +#include // dlopen etc +#include // tolower etc +#include "refprop_wrapper.h" + + + +// Some constants... +const long filepathlength=1024; +const long errormessagelength=255+filepathlength; +const long lengthofreference=3; +const long refpropcharlength=255; +const long ncmax=20; // Note: ncmax is the max number of components + +char *str_replace(char *str, char *search, char *replace, long *count) { + int i,n_ret; + int newlen = strlen(replace); + int oldlen = strlen(search); + char *ret; + *count = 0; + + //count occurrences of searchstring + for (i = 0; oldlen && str[i]; ++i) + if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr + ++*count, i+=oldlen - 1; + } + ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); + if (!ret){ + printf("Could not allocate memory"); + return ""; + } + + if (!*count){ + strncpy(ret,str,n_ret); + //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); + }else{ + i = 0; + while (*str) + if (strstr(str, search) == str) + strncpy(&ret[i], replace,n_ret-i-1), + i += newlen, + str += oldlen; + else + ret[i++] = *str++; + ret[i] = '\0'; + } + return ret; +} + +int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, void* RefpropdllInstance, char* errormsg, int DEBUGMODE){ +// Sets up the interface to the REFPROP.DLL +// is called by props_REFPROP and satprops_REFPROP + char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; + long ierr=0; + + if (strlen(REFPROP_PATH)>filepathlength){ + sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); + return 0; + } + + strcpy(FLD_PATH, REFPROP_PATH); + strcpy(DLL_PATH, REFPROP_PATH); + if (REFPROP_PATH[strlen(REFPROP_PATH)-1]=='\\'){ //if last char is backslash + strcat(DLL_PATH, "refprop.dll"); + strcat(FLD_PATH, "fluids\\"); + }else{//add missing backslash + strcat(DLL_PATH,"\\refprop.dll"); + strcat(FLD_PATH, "\\fluids\\"); + } + + //*RefpropdllInstance = LoadLibrary(DLL_PATH); +// RefpropdllInstance = dlopen(DLL_PATH, RTLD_LAZY); +// if (!RefpropdllInstance){ +// sprintf(errormsg,"ERROR in opening librefprop.so at \"%s\"",DLL_PATH); +// fputs (dlerror(), stderr); +// return 100; +// } + + + char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; + //char hf[refpropcharlength*ncmax]; + char *hf; + + + //parse fluid composition string and insert absolute paths + char replace[filepathlength+6]; + strcpy(replace,".fld|"); + //if (DEBUGMODE) printf("REPLACE: %s\n",replace); + strncat(replace, FLD_PATH,filepathlength-strlen(replace)); + + int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; + hf = (char*) calloc(hf_len, sizeof(char)); + + strncpy(hf,FLD_PATH,hf_len); + strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... + if (++*nX>ncmax){ //...that's why nX is incremented + sprintf(errormsg,"Too many components (More than %i)\n",ncmax); + return 0; + } + (hf,".fld",hf_len-strlen(hf)); + if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); + + strncpy(hfmix,FLD_PATH,filepathlength+1);//add absolute path + strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); + strcpy(hrf,"DEF"); + + +// //...Call SETUP to initialize the program +// SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(*RefpropdllInstance,"SETUPdll"); +// //printf("hf:%s\n hrf: %s\n hfmix: %s\n",hf,hrf,hfmix); +// void (*SETUP)(void); +// void (*SETUP)(void); +// SETUP = dlsym(RefpropdllInstance, "SETUPdll"); +// if ((errormsg = dlerror()) != NULL) { +// fputs(errormsg, stderr); +// exit(1); +// } + + + if (DEBUGMODE) printf("Running SETUPdll...\n"); + SETUPdll(*nX, hf, hfmix, hrf, ierr, herr); + if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); + + +// if (DEBUGMODE) printf("Error code processing...\n"); + switch(ierr){ + case 101: + //strcpy(errormsg,"error in opening file"); +// if (DEBUGMODE) printf("Error 101\n"); + sprintf(errormsg,"error in opening file %s",hf); + break; + case 102: +// if (DEBUGMODE) printf("Error 102\n"); + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: +// if (DEBUGMODE) printf("Error -103\n"); + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: +// if (DEBUGMODE) printf("Error 104\n"); + strcpy(errormsg,"error in setup of model"); + break; + case 105: +// if (DEBUGMODE) printf("Error 105\n"); + strcpy(errormsg,"specified model not found"); + break; + case 111: +// if (DEBUGMODE) printf("Error 111\n"); + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: +// if (DEBUGMODE) printf("Error 112\n"); + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: +// if (DEBUGMODE) printf("Error 114\n"); + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 0: + break; + default: +// if (DEBUGMODE) printf("Unknown error\n"); + strcpy(errormsg,"Unknown error"); + //strcpy(errormsg,"Setup was successful!"); + strncpy(errormsg,herr,errormessagelength); + break; + } + free(hf); + return ierr; +} + + +double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevars: string of any combination of two variables out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevar1,statevar2: values of the two variables specified in statevars + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values (props[0] containing error number) + errormsg: string containing error message +*/ + char statevars[3]; + double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; + long nX,ierr=0; //zero means no error + char herr[errormessagelength+1]; +// HINSTANCE RefpropdllInstance;// Then have windows load the library. + void* RefpropdllInstance; + + if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); + + //initialize interface to REFPROP.dll + + if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ + printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); + return 0; + } + + //CALCULATE MOLAR MASS +// WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); + WMOLdll(x,wm); +// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); + wm /= 1000; //g/mol -> kg/mol + + //identify and assign passed state variables + statevars[0] = tolower(statevars_in[0]); + statevars[1] = tolower(statevars_in[1]); + statevars[2] = '\0'; + if (statevars[0]!='\0'){ + if (statevars[0]==statevars[1]){ + props[0] = 3; + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); + return 0; + } + for (int ii=0;ii<2;ii++){ + val = (ii==0?statevar1:statevar2); + switch(statevars[ii]){ + case 'p': + p = val/1000; //Pa->kPa + break; + case 't': + T = val; + break; + case 's': + s = val*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = val*wm; //J/kg --> kJ/mol + break; + case 'd': + d = val/wm/1000; //kg/m� -> mol/dm� + break; + case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + q = val; + break; + default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ + return 0; + } + } + } + +/* +//...If phase j is known, call TPRHOdll: + long j=2; //phase definition(j=1: Liquid, j=2: Vapor) + long tmp_int=0; + TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); + TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); +*/ +//...If phase is not known, call TPFLSH + double xliq[ncmax],xvap[ncmax],f[ncmax]; + long kq=2;/* additional input--only for TQFLSH and PQFLSH + kq--flag specifying units for input quality + kq = 1 quality on MOLAR basis [moles vapor/total moles] + kq = 2 quality on MASS basis [mass vapor/total mass]*/ +// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); + if (ierr==0){ + if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ +// strcat(errormsg,"Bin in TP!"); + if (phase==2){ //fluid state is known to be two phase +// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); + TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + }else{ +// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); + TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ +/* if (phase==1){ //fluid state is known to be single phase + PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); + PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ +// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ + if (phase==1){ //fluid state is known to be single phase +// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); + PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); + }else{ +// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); + PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); + PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ +// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); + PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ +// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); + PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); +// strcat(errormsg,"Bin in PQ!"); + }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); + THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); + }else{*/ +// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ +// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ +// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); + long kr = 2; + TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ +// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); + TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); + DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); + DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); + DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ +// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); + HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); + DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); + DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); + DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + } + }else + sprintf(errormsg,"Unknown combination of state variables! %s", statevars); + } + + switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE + case 'v': //dynamic viscosity uPa.s + case 'l': //thermal conductivity W/m.K +// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); + TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); + } + + + switch(ierr){ + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 4: + sprintf(errormsg,"P=%f < 0",p); + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",T,p); + break; + case 8: + strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); + break; + case 9: + sprintf(errormsg,"x or T=%f out of range",T); + break; + case 12: + sprintf(errormsg,"x out of range and P=%f < 0",p); + break; + case 13: + sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",d); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",d); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); + break; + default: + strncpy(errormsg,herr,errormessagelength); + } + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOLdll(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOLdll(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� + e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) + cv /= wm; + cp /= wm; + p *= 1000; //kPa->Pa + if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis + eta/=1e6; //uPa.s -> Pa.s + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = e; //inner energy + props[9] = h; //specific enthalpy + props[10] = s;//specific entropy + props[11] = cv; + props[12] = cp; + props[13] = w; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;ii kg/mol + + + //identify and assign passed state variables + statevar[0] = tolower(statevar[0]); + if (statevar[0]!='\0'){ + switch(statevar[0]){ + case 'p': + p = statevarval/1000; //Pa->kPa + break; + case 't': + T = statevarval; + break; + case 'd': + d = statevarval/wm/1000; //kg/m� -> mol/dm� + break; +/* case 's': + s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = statevarval*wm; //J/kg --> kJ/mol + break; +*/ default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable: %c", statevarval); + return 0; + } + } + double xliq[ncmax],xvap[ncmax],f[ncmax]; + + long j=2,kr; +/* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) +*/ + if (ierr==0) + if (~strcmp(statevar,"t")){ +// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); + SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + }else if (~strcmp(statevar,"p")){ +// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); + SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + }else if (~strcmp(statevar,"d")){ +// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); + SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } + + switch(ierr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 8: + strcpy(errormsg,"x out of range"); + break; + case 9: + strcpy(errormsg,"T and x out of range"); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + strncpy(errormsg,herr,errormessagelength); + } + + /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); + SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); + SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOLdll(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOLdll(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� +/* e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) +*/ p *= 1000; //kPa->Pa + } + + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in kPa->Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = 0; + props[8] = 0; //inner energy + props[9] = 0; //specific enthalpy + props[10] = 0;//specific entropy + props[11] = 0; + props[12] = 0; + props[13] = 0; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;ii +#include +#include +#include "refprop_wrapper.h" + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255+1024]; + double* x; + double *props; + double sumx; + int i; + int nX = argc-5; + int DEBUG = 1; + + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); + return 1; + } + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + + + sumx = 0; + for (i=0;i +#ifdef _CRAY +# include +# define RPVersion RPVERSION +# define SETPATHdll SETPATHDLL +# define ABFL1dll ABFL1DLL +# define ABFL2dll ABFL2DLL +# define ACTVYdll ACTVYDLL +# define AGdll AGDLL +# define CCRITdll CCRITDLL +# define CP0dll CP0DLL +# define CRITPdll CRITPDLL +# define CSATKdll CSATKDLL +# define CV2PKdll CV2PKDLL +# define CVCPKdll CVCPKDLL +# define CVCPdll CVCPDLL +# define DBDTdll DBDTDLL +# define DBFL1dll DBFL1DLL +# define DBFL2dll DBFL2DLL +# define DDDPdll DDDPDLL +# define DDDTdll DDDTDLL +# define DEFLSHdll DEFLSHDLL +# define DHD1dll DHD1DLL +# define DHFL1dll DHFL1DLL +# define DHFL2dll DHFL2DLL +# define DHFLSHdll DHFLSHDLL +# define DIELECdll DIELECDLL +# define DOTFILLdll DOTFILLDLL +# define DPDD2dll DPDD2DLL +# define DPDDKdll DPDDKDLL +# define DPDDdll DPDDDLL +# define DPDTKdll DPDTKDLL +# define DPDTdll DPDTDLL +# define DPTSATKdll DPTSATKDLL +# define DSFLSHdll DSFLSHDLL +# define DSFL1dll DSFL1DLL +# define DSFL2dll DSFL2DLL +# define ENTHALdll ENTHALDLL +# define ENTROdll ENTRODLL +# define ESFLSHdll ESFLSHDLL +# define FGCTYdll FGCTYDLL +# define FPVdll FPVDLL +# define GERG04dll GERG04DLL +# define GETFIJdll GETFIJDLL +# define GETKTVdll GETKTVDLL +# define GIBBSdll GIBBSDLL +# define HSFLSHdll HSFLSHDLL +# define INFOdll INFODLL +# define LIMITKdll LIMITKDLL +# define LIMITSdll LIMITSDLL +# define LIMITXdll LIMITXDLL +# define MELTPdll MELTPDLL +# define MELTTdll MELTTDLL +# define MLTH2Odll MLTH2ODLL +# define NAMEdll NAMEDLL +# define PDFL1dll PDFL1DLL +# define PDFLSHdll PDFLSHDLL +# define PEFLSHdll PEFLSHDLL +# define PHFL1dll PHFL1DLL +# define PHFLSHdll PHFLSHDLL +# define PQFLSHdll PQFLSHDLL +# define PREOSdll PREOSDLL +# define PRESSdll PRESSDLL +# define PSFL1dll PSFL1DLL +# define PSFLSHdll PSFLSHDLL +# define PUREFLDdll PUREFLDDLL +# define QMASSdll QMASSDLL +# define QMOLEdll QMOLEDLL +# define SATDdll SATDDLL +# define SATEdll SATEDLL +# define SATHdll SATHDLL +# define SATPdll SATPDLL +# define SATSdll SATSDLL +# define SATTdll SATTDLL +# define SETAGAdll SETAGADLL +# define SETKTVdll SETKTVDLL +# define SETMIXdll SETMIXDLL +# define SETMODdll SETMODDLL +# define SETREFdll SETREFDLL +# define SETUPdll SETUPDLL +# define SPECGRdll SPECGRDLL +# define SUBLPdll SUBLPDLL +# define SUBLTdll SUBLTDLL +# define SURFTdll SURFTDLL +# define SURTENdll SURTENDLL +# define TDFLSHdll TDFLSHDLL +# define TEFLSHdll TEFLSHDLL +# define THERM0dll THERM0DLL +# define THERM2dll THERM2DLL +# define THERM3dll THERM3DLL +# define THERMdll THERMDLL +# define THFLSHdll THFLSHDLL +# define TPFLSHdll TPFLSHDLL +# define TPFL2dll TPFL2DLL +# define TPRHOdll TPRHODLL +# define TQFLSHdll TQFLSHDLL +# define TRNPRPdll TRNPRPDLL +# define TSFLSHdll TSFLSHDLL +# define VIRBdll VIRBDLL +# define VIRCdll VIRCDLL +# define WMOLdll WMOLDLL +# define XMASSdll XMASSDLL +# define XMOLEdll XMOLEdll +#else +# if !defined(_AIX) && !defined(__hpux) +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +# define SPECGRdll specgrdll_ +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +# endif +# define _fcd char * +# define _cptofcd(a,b) (a) +# define _fcdlen(a) strlen(a) +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + // extra function for setup + void RPVersion ( char* ); + void SETPATHdll( const char* ); + // + void ABFL1dll(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void ABFL2dll(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + void ACTVYdll(double &,double &,double *,double &); + void AGdll(double &,double &,double *,double &,double &); + void CCRITdll(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + void CP0dll(double &,double *,double &); + void CRITPdll(double *,double &,double &,double &,long &,char*,long ); + void CSATKdll(long &,double &,long &,double &,double &,double &,long &,char*,long ); + void CV2PKdll(long &,double &,double &,double &,double &,long &,char*,long ); + void CVCPKdll(long &,double &,double &,double &,double &); + void CVCPdll(double &,double &,double *,double &,double &); + void DBDTdll(double &,double *,double &); + void DBFL1dll(double &,double &,double *,double &,double &,double &,long &,char*,long ); + void DBFL2dll(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + void DDDPdll(double &,double &,double *,double &); + void DDDTdll(double &,double &,double *,double &); + void DEFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void DHD1dll(double &,double &,double *,double &,double &,double &,double &,double &,double &); + void DHFL1dll(double &,double &,double *,double &,long &,char*,long );//added by henning francke + void DHFL2dll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke + void DHFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void DIELECdll(double &,double &,double *,double &); + void DOTFILLdll(long &,double *,double &,double &,long &,char*,long ); + void DPDD2dll(double &,double &,double *,double &); + void DPDDKdll(long &,double &,double &,double &); + void DPDDdll(double &,double &,double *,double &); + void DPDTKdll(long &,double &,double &,double &); + void DPDTdll(double &,double &,double *,double &); + void DPTSATKdll(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + void DSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void DSFL1dll(double &,double &,double *,double &,long &,char*,long );//added by henning francke + void DSFL2dll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke + void ENTHALdll(double &,double &,double *,double &); + void ENTROdll(double &,double &,double *,double &); + void ESFLSHdll(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + void FGCTYdll(double &,double &,double *,double *); + void FPVdll(double &,double &,double &,double *,double &); + void GERG04dll(long &,long &,long &,char*,long ); + void GETFIJdll(char*,double *,char*,char*,long ,long ,long ); + void GETKTVdll(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + void GIBBSdll(double &,double &,double *,double &,double &); + void HSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + void INFOdll(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + void LIMITKdll(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + void LIMITSdll(char*,double *,double &,double &,double &,double &,long ); + void LIMITXdll(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + void MELTPdll(double &,double *,double &,long &,char*,long ); + void MELTTdll(double &,double *,double &,long &,char*,long ); + void MLTH2Odll(double &,double &,double &); + void NAMEdll(long &,char*,char*,char*,long ,long ,long ); + void PDFL1dll(double &,double &,double *,double &,long &,char*,long ); + void PDFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void PEFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void PHFL1dll(double &,double &,double *,long &,double &,double &,long &,char*,long ); + void PHFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void PQFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void PREOSdll(long &); + void PRESSdll(double &,double &,double *,double &); + void PSFL1dll(double &,double &,double *,long &,double &,double &,long &,char*,long ); + void PSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void PUREFLDdll(long &); + void QMASSdll(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + void QMOLEdll(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + void SATDdll(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + void SATEdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + void SATHdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + void SATPdll(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + void SATSdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + void SATTdll(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + void SETAGAdll(long &,char*,long ); + void SETKTVdll(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + void SETMIXdll(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + void SETMODdll(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + void SETREFdll(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + //void SETUPdll(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + void SETUPdll(long &,char*,char*,char*,long &,char*); + void SPECGRdll(double &,double &,double &,double &); + void SUBLPdll(double &,double *,double &,long &,char*,long ); + void SUBLTdll(double &,double *,double &,long &,char*,long ); + void SURFTdll(double &,double &,double *,double &,long &,char*,long ); + void SURTENdll(double &,double &,double &,double *,double *,double &,long &,char*,long ); + void TDFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void TEFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void THERM0dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + void THERM2dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + void THERM3dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + void THERMdll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + void THFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void TPFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void TPFL2dll(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke + void TPRHOdll(double &,double &,double *,long &,long &,double &,long &,char*,long ); + void TQFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void TRNPRPdll(double &,double &,double *,double &,double &,long &,char*,long ); + void TSFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + void VIRBdll(double &,double *,double &); + void VIRCdll(double &,double *,double &); + void WMOLdll(double *,double &); + void XMASSdll(double *,double *,double &); + void XMOLEdll(double *,double *,double &); +#ifdef __cplusplus +} // extern "C" +#endif +// REFPROP_H +#endif +// routines used in henning francke's wrapper +// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, +// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD +// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 +// diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp new file mode 100644 index 0000000..5441064 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp @@ -0,0 +1,233 @@ +/* + * ============================================================================ + * Name : refprop-ftn.cpp + * Author : Jorrit Wronski (jowr@mek.dtu.dk) + * Version : 0.1 + * Copyright : Use and modify at your own risk. + * Description : example for Fortran and CPP interoperation. This file is + * based on EX_C1.CPP by Chris Muzny and EX_C2.c by Ian Bell. + * The example files can be obtained online from NIST + * http://www.boulder.nist.gov/div838/theory/refprop/Frequently_asked_questions.htm + * ============================================================================ + */ + +#include +#include /* EXIT_SUCCESS */ +#include /* strlen, memset, memcpy, memchr */ +#include /* refprop header file */ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#define refpropcharlength 255 +#define filepathlength 255 +#define maxstringlength 10000 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +void newline() { + printf("%s","\n"); +} + + +int main(int argc, char* argv[]) { + static long i,ierr,info_index; + static double wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas; + static char hfld[maxstringlength+1],hrf[lengthofreference+1],herr[errormessagelength+1],hfm[refpropcharlength+1]; + static char v[refpropcharlength+1],hpth[filepathlength+1]; + + static double x[ncmax],xliq[ncmax],xvap[ncmax],f[ncmax]; + + double t=100.0; + double p,dl,dv; + + newline(); + + RPVersion(v); + printf("RPVersion(v) returned v = %s\n", v); + + strcpy(hpth,"/home/jowr/Documents/Fluids/refprop/v9.0/"); + SETPATHdll(hpth); + printf("SETPATHdll(hpth) called with hpth = %s\n", hpth); + + i=1; + strcpy(hfld,"nitrogen.fld"); + strcpy(hfm,"hmx.bnc"); + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + SETUPdll(i,hfld,hfm,hrf,ierr,herr); + if (ierr != 0) printf("%s\n",herr); + printf("SETUPdll(i,hfld,hfm,hrf,ierr,herr) called with hfld = %s\n", hfld); + + info_index = 1; + INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas); + printf("INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas) called with index = %l\n", info_index); + printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); + printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); + + //...For a mixture, use the following setup instead of the lines above. + // Use "|" as the file name delimiter for mixtures + i=3; + strcpy(hfld,"nitrogen.fld"); + strcat(hfld,"|argon.fld"); + strcat(hfld,"|oxygen.fld"); + strcpy(hfm,"hmx.bnc"); + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + x[0]=.7812; //Air composition + x[1]=.0092; + x[2]=.2096; + //...Call SETUP to initialize the program + SETUPdll(i,hfld,hfm,hrf,ierr,herr); + newline(); + printf("SETUPdll(i,hfld,hfm,hrf,ierr,herr) called with hfld = %s\n", hfld); + + INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas); + printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); + printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); + + //...Calculate molecular weight of a mixture + wm = 0.; + WMOLdll(x,wm); + newline(); + printf("wm %10.4f\n",wm); + + //...Get saturation properties given t,x; for i=1: x is liquid phase + //..... for i=2: x is vapor phase + + SATTdll(t,x,i,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + i=2; + SATTdll(t,x,i,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + + //...Calculate saturation properties at a given p. i is same as SATT + i=2; + SATPdll(p,x,i,t,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + printf("T,Dl,Dv,xl(1),xv(1) %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,dl,dv,xliq[0],xvap[0]); + + //...Other saturation routines are given in SAT_SUB.FOR + t=300.0; + p=20000.0; + + //...Calculate d from t,p,x + //...If phase is known: (j=1: Liquid, j=2: Vapor) + long j=1; + double d,q,e,h,s,cv,cp,w,b,c, + dpdrho,d2pdd2,dpdt,dhdt_d,dhdt_p,dhdp_t,dhdp_d, + sigma,dhdd_t,dhdd_p,eta,tcx,pp,tt,hjt,h1,dd; + long tmp_int=0; + TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); + printf("T,P,D %10.4f,%10.4f,%10.4f\n",t,p,d); + + //...If phase is not known, call TPFLSH + //...Calls to TPFLSH are much slower than TPRHO since SATT must be called first. + //.....(If two phase, quality is returned as q) + TPFLSHdll(t,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T,P,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,p,d,h,cp); + + //...Calculate pressure (p), internal energy (e), enthalpy (h), entropy (s), + //.....isochoric (cv) and isobaric (cp) heat capacities, speed of sound (w), + //.....and Joule-Thomson coefficient (hjt) from t,d,x + //.....(subroutines THERM2 and THERM3 contain more properties, see PROP_SUB.FOR) + THERMdll(t,d,x,p,e,h,s,cv,cp,w,hjt); + + //...Calculate pressure + PRESSdll(t,d,x,p); + + //...Calculate fugacity + FGCTYdll(t,d,x,f); + + //...Calculate second and third virial coefficients + VIRBdll (t,x,b); + VIRCdll (t,x,c); + printf("F,B,C %10.4f,%10.4f,%10.4f\n",f[0],b,c); + + //...Calculate the derivatives: dP/dD, d^2P/dD^2, dP/dT (D indicates density) + //...(dD/dP, dD/dT, and dB/dT are also available, see PROP_SUB.FOR) + DPDDdll (t,d,x,dpdrho); + DPDD2dll (t,d,x,d2pdd2); + DPDTdll (t,d,x,dpdt); + printf("dP/dD,d2P/dD2,dP/dT %10.4f,%10.4f,%10.4f\n",dpdrho,d2pdd2,dpdt); + + + //...Calculate derivatives of enthalpy with respect to T, P, and D + DHD1dll(t,d,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d); + printf("Enthalpy derivatives %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n", + dhdt_d,dhdt_p,dhdd_t,dhdd_p/1000.0,dhdp_t); + //...Calculate surface tension + SURFTdll (t,dl,x,sigma,ierr,herr,errormessagelength); + printf("T,SURF. TN. %10.4f,%10.4f\n",t,sigma); + + //...Calculate viscosity (eta) and thermal conductivity (tcx) + TRNPRPdll (t,d,x,eta,tcx,ierr,herr,errormessagelength); + printf("VIS.,TH.CND. %10.4f,%10.4f\n",eta,tcx*1000.0); + + //...General property calculation with inputs of t,d,x + TDFLSHdll (t,d,x,pp,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from TDFLSH %10.4f,%10.4f,%10.4f\n",t,d,pp/1000.0); + + //...General property calculation with inputs of p,d,x + PDFLSHdll (p,d,x,tt,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from PDFLSH %10.4f,%10.4f,%10.4f\n",tt,d,p/1000.0); + + //...General property calculation with inputs of p,h,x + PHFLSHdll (p,h,x,tt,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from PHFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + + //...General property calculation with inputs of p,s,x + PSFLSHdll (p,s,x,tt,dd,dl,dv,xliq,xvap,q,e,h1,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from PSFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + + //...General property calculation with inputs of d,h,x + DHFLSHdll (d,h,x,tt,pp,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from DHFLSH %10.4f,%10.4f,%10.4f\n",tt,d,pp/1000.0); + + //...General property calculation with inputs of t,h,x + // kr--flag specifying desired root for multi-valued inputs: + // 1=return lower density root + // 2=return higher density root + long kr=1; + THFLSHdll (t,h,x, + kr,pp,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + printf("T, D, P from THFLSH %10.4f,%10.4f,%10.4f\n",t,dd,pp/1000.0); + + //...Other general property calculation routines are given in FLSH_SUB.FOR + //...and FLASH2.FOR + + //...Calculate melting pressure + t=100.0; + MELTTdll (t,x,p,ierr,herr,errormessagelength); + printf("Melting pressure(MPa) %10.4f,%10.4f\n",p/1000.0,t); + + //...Calculate melting temperature + MELTPdll (p,x,tt,ierr,herr,errormessagelength); + printf("Melting temperature(K)%10.4f,%10.4f\n",tt,p/1000.0); + + //...Calculate sublimation pressure + t=200.0; + SUBLTdll (t,x,p,ierr,herr,errormessagelength); + printf("Sublimation pr.(kPa) %10.4f,%10.4f\n",p,t); + + //...Calculate sublimation temperature + SUBLPdll (p,x,tt,ierr,herr,errormessagelength); + printf("Sublimation temp.(K) %10.4f,%10.4f\n",tt,p); + + //...Get limits of the equations and check if t,d,p is a valid point + //...Equation of state + // call LIMITK ('EOS',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) + //...Viscosity equation + // call LIMITK ('ETA',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) + //...Thermal conductivity equation + // call LIMITK ('TCX',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) + + //...Other routines are given in UTILITY.FOR + + +return EXIT_SUCCESS; +} + diff --git a/package.mo b/package.mo index 1f78dfe..a773821 100644 --- a/package.mo +++ b/package.mo @@ -1,7 +1,7 @@ within ; package MediaTwoPhaseMixture - constant String REFPROP_PATH = "d:\\Program Files (x86)\\REFPROP\\"; - +// constant String REFPROP_PATH = "d:\\Program Files (x86)\\REFPROP\\"; + constant String REFPROP_PATH = "/home/jowr/Documents/Fluids/refprop/v9.0/"; annotation (version="0.2", uses(Modelica(version="3.2")), Documentation(info=" From 689bd29962af7173b916850b07b3cfe8b1fac3bb Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 19 Sep 2012 04:07:08 -0700 Subject: [PATCH 02/57] 2012:09:19 13:06 - Test file compiles and works, code cannot be used from within Dymola. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 60 +- .../Version 0.5_linux/refprop_wrapper.cpp | 48 +- .../Version 0.5_linux/refpropwrappertest.cpp | 3 +- .../Version 0.5_linux/src/PASS_FTN_LIN.FOR | 1364 ----------------- .../src/PASS_FTN_LIN.FOR.tpl | 68 + 5 files changed, 149 insertions(+), 1394 deletions(-) delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index 4fb8093..d951e9d 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -7,12 +7,20 @@ # ============================================================================ # used for the output -BINDIR =. THENAME =refprop - THEWRAPPER =refprop_wrapper THETEST =refpropwrappertest +########################################################### +# Setting the directories for library, header and +# binary files created in this makefile. +########################################################### +LIBDIR =/home/jowr/Documents/Fluids/refprop/v9.0 +DYMDIR =/opt/dymola +LIBINST =$(DYMDIR)/bin/lib +HEADINST =$(DYMDIR)/source +BINDIR =. + ########################################################### # Change these lines if you are using a different Fortran # compiler or if you would like to use other flags. @@ -33,7 +41,6 @@ CPPFLAGS =-O2 -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-d # the library file. ########################################################### LIBFLAGS =-rdynamic -fPIC -shared -LIBDIR =/home/jowr/Documents/Fluids/refprop/v9.0 LIBRARY =lib$(THENAME) LIBFILE =PASS_FTN_LIN DYNAMICLIBRARYEXTENSION =.so @@ -69,30 +76,46 @@ LIBOBJECTFILES = \ $(LIBDIR)/fortran/TRNS_VIS.o \ $(LIBDIR)/fortran/TRNSP.o \ $(LIBDIR)/fortran/UTILITY.o - + +########################################################### +# Link all files to places recognised by the system. +########################################################### +.PHONY : install +install : all + ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) + ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) + ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) + ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : all +all : library libheader wrapper wrapheader ########################################################### # Compile the wrapper class and its tests. ########################################################### +.PHONY : wrapheader +wrapheader : $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) +$(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION): $(THEWRAPPER)$(HEADEREXTENSION) + cp $(THEWRAPPER)$(HEADEREXTENSION) $(LIBDIR) + .PHONY : wrapper -wrapper : $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) -$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) +wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) +$(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o library libheader + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) .PHONY : test test : $(THETEST) -$(THETEST) : $(THETEST).o $(THEWRAPPER).o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) - $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o $(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) +$(THETEST) : $(THETEST).o wrapper wrapheader + $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o -l$(THEWRAPPER) ########################################################### # Compile the Fortran sources into a library file that can # be used as a shared object. ########################################################### -.PHONY : libinstall -libinstall : library libheader - ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) - .PHONY : libheader libheader : $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION): src/$(HEADERFILE)$(HEADEREXTENSION) @@ -102,6 +125,13 @@ $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION): src/$(HEADERFILE)$(HEADEREXTENSION) library : $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION): src/$(LIBFILE).o $(LIBOBJECTFILES) $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) src/$(LIBFILE).o $(LIBOBJECTFILES) + +src/$(LIBFILE).FOR: $(LIBDIR)/fortran/PASS_FTN.FOR + sed 's/dll_export/!dll_export/g' $(LIBDIR)/fortran/PASS_FTN.FOR > src/$(LIBFILE).FOR + cat src/$(LIBFILE).FOR.tpl >> src/$(LIBFILE).FOR + +# sed -i 's/*10000/(10000)/g' src/$(LIBFILE).FOR +# sed -i 's/*255/(255)/g' src/$(LIBFILE).FOR $(LIBDIR)/fortran/%.o: $(LIBDIR)/fortran/%.FOR $(FC) $(FFLAGS) -o $(LIBDIR)/fortran/$*.o -c $< @@ -123,7 +153,7 @@ src/%.o : src/%.cpp .PHONY: clean clean: - $(RM) **.o **.so **.mod $(BINDIR)/RP-ftn + $(RM) **.o **.so **.mod $(BINDIR)/RP-ftn src/$(LIBFILE).FOR $(THETEST) ########################################################### # Compile a simple example to illustrate the connection diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp index d2a7c92..31def50 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp @@ -25,17 +25,21 @@ //#define DEBUGMODE 1 -//#include #include -#include -#include -#include -#include // dlopen etc -#include // tolower etc +#if defined(WIN32) || defined(_WIN32) +# include +# include "REFPROP_dll.h" +#else // assuming Linux system +# include +# include +# include +//# include // dlopen etc +# include // tolower etc +#endif +//# error "Could not determine system." #include "refprop_wrapper.h" - // Some constants... const long filepathlength=1024; const long errormessagelength=255+filepathlength; @@ -43,6 +47,19 @@ const long lengthofreference=3; const long refpropcharlength=255; const long ncmax=20; // Note: ncmax is the max number of components +static char const GB_optId = '-' ; // - under UNIX +static char const GB_altOptId = '+' ; // + under UNIX +static char const GB_asciiEsc = '\\' ; // under UNIX +static char* const GB_preferredPathSep = "/" ; // / under UNIX +static char const GB_allowedPathSep[] = "/" ; +static bool const GB_ignoreCase = false ; // in filenames only. +static char const GB_stdinName[] = "-" ; +static int const GB_exitSuccess = 0 ; +static int const GB_exitWarning = 1 ; +static int const GB_exitError = 2 ; +static int const GB_exitFatal = 3 ; +static int const GB_exitInternal = 4 ; + char *str_replace(char *str, char *search, char *replace, long *count) { int i,n_ret; int newlen = strlen(replace); @@ -91,12 +108,15 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, voi strcpy(FLD_PATH, REFPROP_PATH); strcpy(DLL_PATH, REFPROP_PATH); - if (REFPROP_PATH[strlen(REFPROP_PATH)-1]=='\\'){ //if last char is backslash - strcat(DLL_PATH, "refprop.dll"); - strcat(FLD_PATH, "fluids\\"); + if (REFPROP_PATH[strlen(REFPROP_PATH)-1]==*GB_preferredPathSep){ //if last char is backslash +// strcat(DLL_PATH, "refprop.dll"); + strcat(FLD_PATH, "fluids"); + strcat(FLD_PATH, GB_preferredPathSep); }else{//add missing backslash - strcat(DLL_PATH,"\\refprop.dll"); - strcat(FLD_PATH, "\\fluids\\"); +// strcat(DLL_PATH,"\\refprop.dll"); + strcat(FLD_PATH, GB_preferredPathSep); + strcat(FLD_PATH, "fluids"); + strcat(FLD_PATH, GB_preferredPathSep); } //*RefpropdllInstance = LoadLibrary(DLL_PATH); @@ -115,7 +135,7 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, voi //parse fluid composition string and insert absolute paths char replace[filepathlength+6]; - strcpy(replace,".fld|"); + strcpy(replace,".FLD|"); //if (DEBUGMODE) printf("REPLACE: %s\n",replace); strncat(replace, FLD_PATH,filepathlength-strlen(replace)); @@ -128,7 +148,7 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, voi sprintf(errormsg,"Too many components (More than %i)\n",ncmax); return 0; } - (hf,".fld",hf_len-strlen(hf)); + strncat(hf,".FLD",hf_len-strlen(hf)); if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); strncpy(hfmix,FLD_PATH,filepathlength+1);//add absolute path diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp index b726bbf..377b89e 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp @@ -20,7 +20,8 @@ int main(int argc, char* argv[]){ int DEBUG = 1; if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); + printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/home/jowr/Documents/Fluids/refprop/v9.0/\" .1\n"); return 1; } diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR b/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR deleted file mode 100644 index 0ff5953..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR +++ /dev/null @@ -1,1364 +0,0 @@ - subroutine RPVersion (v) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_RPVersion"::RPVersion -cDEC$ ATTRIBUTES STDCALL, REFERENCE::RPVersion - !dll_export RPVersion - character v*255 - v='8.01c' - end -c ====================================================================== -c subroutine WRTREFdll(fxname) -c implicit double precision (a-h,o-z) -c implicit integer (i-n) -c character*255 fxname -c !dll_export WRTREFdll -c call WRTREF (fxname,-1,1,0,0,0) -c end -c -c subroutine MINIMIZEdll(fxname,idfile,mn,i) -c implicit double precision (a-h,o-z) -c implicit integer (i-n) -c character*255 fxname,idfile -c double precision mn(200) -c !dll_export MINIMIZEdll -c call minimize(fxname,idfile,mn,i) -c end -c -c subroutine FOFXdll(mn,i,fofxx,ierr,herr) -c implicit double precision (a-h,o-z) -c implicit integer (i-n) -c character*255 herr -c double precision mn(200) -c !dll_export FOFXdll -c call fofx(mn,i,fofxx,ierr,herr) -c end -c ====================================================================== - -c ====================================================================== -c begin file pass_ftn.for -c -c This file defines the DLL-callable routines which would be used by -c Visual Basic, Excel, and other applications to access the main -c Fortran code. It is not needed when compiling Fortran applications. -c It is only used when compiling the DLL and contains commands specific -c to the Lahey/Fujitsu Fortran 95 Compiler. When using other compilers, -c the lines with '!dll_export' should be commented out. -c -c The calling sequence is identical (except for the SETUPdll routine) to -c the main Fortran routines, with the letters 'dll' appended to the routine -c name. See the Excel sample file or the Visual Basic 'SAMPLE.BAS' -c file for usage information. -c -c ====================================================================== -c - subroutine SETUPdll (i,hfld,hfm,hrf,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-k,m,n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETUPdll"::SETUPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETUPdll - !dll_export SETUPdll - character hfld*10000,hfm*255,hrf*3,herr*255 - call SETUP0 (i,hfld,hfm,hrf,ierr,herr) - end -c ====================================================================== - subroutine SETREFdll (hrf,ixflag,x0,h0,s0,t0,p0,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr - character*3 hrf -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETREFdll"::SETREFdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETREFdll - !dll_export SETREFdll - dimension x0(ncmax) - call SETREF (hrf,ixflag,x0,h0,s0,t0,p0,ierr,herr) - end -c ====================================================================== - subroutine SETMIXdll (hmxnme,hfmix,hrf,ncc,hfile,x,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 hmxnme,hfmix,hfiles(ncmax),herr - character hfile*10000,hrf*3 - dimension x(ncmax) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETMIXdll"::SETMIXdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETMIXdll - !dll_export SETMIXdll - call SETMIX (hmxnme,hfmix,hrf,ncc,hfiles,x,ierr,herr) - hfile=hfiles(1) - j=index(hfile,' ') - hfile=hfile(1:j-1)//'|' - do i=2,ncc - j=index(hfile,' ') - hfile=hfile(1:j-1)//hfiles(i) - j=index(hfile,' ') - hfile=hfile(1:j-1)//'|' - enddo - end -c ====================================================================== - subroutine SETMODdll (nc,htype,hmix,hcomp2,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr - character*60 hcomp2 - character*3 htype,hmix,hcomp(1:ncmax) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETMODdll"::SETMODdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETMODdll - !dll_export SETMODdll - do i=1,ncmax - hcomp(i)=hcomp2(i*3-2:i*3) - enddo - call SETMOD (nc,htype,hmix,hcomp,ierr,herr) - end -c ====================================================================== - subroutine PUREFLDdll (icomp) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PUREFLDdll"::PUREFLDdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PUREFLDdll - !dll_export PUREFLDdll - call PUREFLD (icomp) - end -c ====================================================================== - subroutine SETNCdll (ncomp) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETNCdll"::SETNCdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETNCdll - !dll_export SETNCdll - call SETNC (ncomp) - end -c ====================================================================== - subroutine SETPATHdll (hpth) - character hpth*255 -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETPATHdll"::SETPATHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETPATHdll - !dll_export SETPATHdll - call SETPATH (hpth) - end -c ====================================================================== - subroutine UNSETAGAdll -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_UNSETAGAdll"::UNSETAGAdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::UNSETAGAdll - !dll_export UNSETAGAdll - call UNSETAGA - end -c ====================================================================== - subroutine CRITPdll (x,tcrit,pcrit,Dcrit,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CRITPdll"::CRITPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CRITPdll - !dll_export CRITPdll - dimension x(ncmax) - call CRITP (x,tcrit,pcrit,Dcrit,ierr,herr) - end -c ====================================================================== - subroutine THERMdll (t,rho,x,p,e,h,s,cv,cp,w,hjt) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_THERMdll"::THERMdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::THERMdll - !dll_export THERMdll - dimension x(ncmax) - call THERM (t,rho,x,p,e,h,s,cv,cp,w,hjt) - end -c ====================================================================== - subroutine THERM0dll (t,rho,x,p,e,h,s,cv,cp,w,a,g) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_THERM0dll"::THERM0dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::THERM0dll - !dll_export THERM0dll - dimension x(ncmax) - call THERM0 (t,rho,x,p,e,h,s,cv,cp,w,a,g) - end -c ====================================================================== - subroutine THERM2dll (t,rho,x,p,e,h,s,cv,cp,w,Z,hjt,A,G,xkappa, - & beta,dPdD,d2PdD2,dPdT,dDdT,dDdP, - & d2PT2,d2PdTD,spare3,spare4) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_THERM2dll"::THERM2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::THERM2dll - !dll_export THERM2dll - dimension x(ncmax) - call THERM2 (t,rho,x,p,e,h,s,cv,cp,w,Z,hjt,A,G,xkappa,beta, - & dPdD,d2PdD2,dPdT,dDdT,dDdP, - & d2PT2,d2PdTD,spare3,spare4) - end -c ====================================================================== - subroutine THERM3dll (t,rho,x, - & xkappa,beta,xisenk,xkt,betas,bs,xkkt,thrott,pi,spht) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_THERM3dll"::THERM3dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::THERM3dll - !dll_export THERM3dll - dimension x(ncmax) - call THERM3 (t,rho,x, - & xkappa,beta,xisenk,xkt,betas,bs,xkkt,thrott,pi,spht) - end -c ====================================================================== - subroutine RESIDUALdll (t,rho,x,pr,er,hr,sr,cvr,cpr,Ar,Gr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_RESIDUALdll"::RESIDUALdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::RESIDUALdll - !dll_export RESIDUALdll - dimension x(ncmax) - call RESIDUAL (t,rho,x,pr,er,hr,sr,cvr,cpr,Ar,Gr) - end -c ====================================================================== - subroutine ENTROdll (t,rho,x,s) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ENTROdll"::ENTROdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ENTROdll - !dll_export ENTROdll - dimension x(ncmax) - call ENTRO (t,rho,x,s) - end -c ====================================================================== - subroutine ENTHALdll (t,rho,x,h) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ENTHALdll"::ENTHALdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ENTHALdll - !dll_export ENTHALdll - dimension x(ncmax) - call ENTHAL (t,rho,x,h) - end -c ====================================================================== - subroutine CVCPdll (t,rho,x,cv,cp) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CVCPdll"::CVCPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CVCPdll - !dll_export CVCPdll - dimension x(ncmax) - call CVCP (t,rho,x,cv,cp) - end -c ====================================================================== - subroutine CVCPKdll (icomp,t,rho,cv,cp) - implicit double precision (a-h,o-z) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CVCPKdll"::CVCPKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CVCPKdll - !dll_export CVCPKdll - call CVCPK (icomp,t,rho,cv,cp) - end -c ====================================================================== - subroutine GIBBSdll (t,rho,x,Ar,Gr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_GIBBSdll"::GIBBSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::GIBBSdll - !dll_export GIBBSdll - dimension x(ncmax) - call GIBBS (t,rho,x,Ar,Gr) - end -c ====================================================================== - subroutine AGdll (t,rho,x,a,g) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_AGdll"::AGdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::AGdll - !dll_export AGdll - dimension x(ncmax) - call AG (t,rho,x,a,g) - end -c ====================================================================== - subroutine PRESSdll (t,rho,x,p) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PRESSdll"::PRESSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PRESSdll - !dll_export PRESSdll - dimension x(ncmax) - call PRESS (t,rho,x,p) - end -c ====================================================================== - subroutine DPDDdll (t,rho,x,dpdrho) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPDDdll"::DPDDdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPDDdll - !dll_export DPDDdll - dimension x(ncmax) - call DPDD (t,rho,x,dpdrho) - end -c ====================================================================== - subroutine DPDDKdll (icomp,t,rho,dpdrho) - implicit double precision (a-h,o-z) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPDDKdll"::DPDDKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPDDKdll - !dll_export DPDDKdll - call DPDDK (icomp,t,rho,dpdrho) - end -c ====================================================================== - subroutine DPDD2dll (t,rho,x,d2PdD2) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPDD2dll"::DPDD2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPDD2dll - !dll_export DPDD2dll - dimension x(ncmax) - call DPDD2 (t,rho,x,d2PdD2) - end -c ====================================================================== - subroutine DPDTdll (t,rho,x,dpt) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPDTdll"::DPDTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPDTdll - !dll_export DPDTdll - dimension x(ncmax) - call DPDT (t,rho,x,dpt) - end -c ====================================================================== - subroutine DPDTKdll (icomp,t,rho,dpt) - implicit double precision (a-h,o-z) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPDTKdll"::DPDTKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPDTKdll - !dll_export DPDTKdll - call DPDTK (icomp,t,rho,dpt) - end -c ====================================================================== - subroutine DDDPdll (t,rho,x,drhodp) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DDDPdll"::DDDPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DDDPdll - !dll_export DDDPdll - dimension x(ncmax) - call DDDP (t,rho,x,drhodp) - end -c ====================================================================== - subroutine DDDTdll (t,rho,x,drhodt) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DDDTdll"::DDDTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DDDTdll - !dll_export DDDTdll - dimension x(ncmax) - call DDDT (t,rho,x,drhodt) - end -c ====================================================================== - subroutine DHD1dll (t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t, - & dhdp_d) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHD1dll"::DHD1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHD1dll - !dll_export DHD1dll - dimension x(ncmax) - call DHD1 (t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d) - end -c ====================================================================== - subroutine FGCTYdll (t,rho,x,f) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_FGCTYdll"::FGCTYdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::FGCTYdll - !dll_export FGCTYdll - dimension x(ncmax),f(ncmax) - call FGCTY (t,rho,x,f) - end -c ====================================================================== - subroutine FGCTY2dll (t,rho,x,f,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_FGCTY2dll"::FGCTY2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::FGCTY2dll - !dll_export FGCTY2dll - dimension x(ncmax),f(ncmax) - call FGCTY2 (t,rho,x,f,ierr,herr) - end -c ====================================================================== - subroutine FUGCOFdll (t,rho,x,f,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_FUGCOFdll"::FUGCOFdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::FUGCOFdll - !dll_export FUGCOFdll - dimension x(ncmax),f(ncmax) - call FUGCOF (t,rho,x,f,ierr,herr) - end -c ====================================================================== - subroutine CHEMPOTdll (t,rho,x,u,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CHEMPOTdll"::CHEMPOTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CHEMPOTdll - !dll_export CHEMPOTdll - dimension x(ncmax),u(ncmax) - call CHEMPOT (t,rho,x,u,ierr,herr) - end -c ====================================================================== - subroutine ACTVYdll (t,rho,x,actv,gamma,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ACTVYdll"::ACTVYdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ACTVYdll - !dll_export ACTVYdll - dimension x(ncmax),actv(ncmax),gamma(ncmax) - call ACTVY (t,rho,x,actv,gamma,ierr,herr) - end -c ====================================================================== - subroutine VIRBdll (t,x,b) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_VIRBdll"::VIRBdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::VIRBdll - !dll_export VIRBdll - dimension x(ncmax) - call VIRB (t,x,b) - end -c ====================================================================== - subroutine B12dll (t,x,b) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_B12dll"::B12dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::B12dll - !dll_export B12dll - dimension x(ncmax) - call B12 (t,x,b) - end -c ====================================================================== - subroutine DBDTdll (t,x,b) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DBDTdll"::DBDTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DBDTdll - !dll_export DBDTdll - dimension x(ncmax) - call DBDT (t,x,b) - end -c ====================================================================== - subroutine VIRCdll (t,x,c) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_VIRCdll"::VIRCdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::VIRCdll - !dll_export VIRCdll - dimension x(ncmax) - call VIRC (t,x,c) - end -c ====================================================================== - subroutine VIRBAdll (t,x,b) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_VIRBAdll"::VIRBAdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::VIRBAdll - !dll_export VIRBAdll - dimension x(ncmax) - call VIRBA (t,x,b) - end -c ====================================================================== - subroutine VIRCAdll (t,x,c) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_VIRCAdll"::VIRCAdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::VIRCAdll - !dll_export VIRCAdll - dimension x(ncmax) - call VIRCA (t,x,c) - end -c ====================================================================== - subroutine HEATdll (t,rho,x,hg,hn,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_HEATdll"::HEATdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::HEATdll - !dll_export HEATdll - dimension x(ncmax) - CALL HEAT (t,rho,x,hg,hn,ierr,herr) - end -c ====================================================================== - subroutine SATTPdll (t,p,x,kph,iGuess,d,rhol,rhov,xliq,xvap,q, - & ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATTPdll"::SATTPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATTPdll - !dll_export SATTPdll - dimension x(ncmax),xliq(ncmax),xvap(ncmax) - call SATTP (t,p,x,kph,iGuess,d,rhol,rhov,xliq,xvap,q,ierr,herr) - end -c ====================================================================== - subroutine SATTdll (t,x,kph,p,rhol,rhov,xliq,xvap,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATTdll"::SATTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATTdll - !dll_export SATTdll - dimension x(ncmax),xliq(ncmax),xvap(ncmax) - call SATT (t,x,kph,p,rhol,rhov,xliq,xvap,ierr,herr) - end -c ====================================================================== - subroutine SATPdll (p,x,kph,t,rhol,rhov,xliq,xvap,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATPdll"::SATPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATPdll - !dll_export SATPdll - dimension x(ncmax),xliq(ncmax),xvap(ncmax) - call SATP (p,x,kph,t,rhol,rhov,xliq,xvap,ierr,herr) - end -c ====================================================================== - subroutine SATDdll (rho,x,kph,kr,t,p,rhol,rhov,xliq,xvap,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATDdll"::SATDdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATDdll - !dll_export SATDdll - dimension x(ncmax),xliq(ncmax),xvap(ncmax) - call SATD (rho,x,kph,kr,t,p,rhol,rhov,xliq,xvap,i,herr) - end -c ====================================================================== - subroutine SATHdll (h,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATHdll"::SATHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATHdll - !dll_export SATHdll - dimension x(ncmax) - call SATH (h,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2,i,herr) - end -c ====================================================================== - subroutine SATEdll (e,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATEdll"::SATEdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATEdll - !dll_export SATEdll - dimension x(ncmax) - call SATE (e,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2,i,herr) - end -c ====================================================================== - subroutine SATSdll (s,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2, - & k3,t3,p3,d3,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATSdll"::SATSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATSdll - !dll_export SATSdll - dimension x(ncmax) - call SATS (s,x,kph,nroot,k1,t1,p1,d1,k2,t2,p2,d2, - & k3,t3,p3,d3,ierr,herr) - end -c ====================================================================== - subroutine SATTESTdll (t,x,kph,p,x2,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATTESTdll"::SATTESTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATTESTdll - !dll_export SATTESTdll - dimension x(ncmax),x2(ncmax) - call SATTEST (t,x,kph,p,x2,ierr,herr) - end -c ====================================================================== - subroutine SATPESTdll (p,x,kph,t,x2,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SATPESTdll"::SATPESTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SATPESTdll - !dll_export SATPESTdll - dimension x(ncmax),x2(ncmax) - call SATPEST (p,x,kph,t,x2,ierr,herr) - end -c ====================================================================== - subroutine CSATKdll (icomp,t,kph,p,rho,csat,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CSATKdll"::CSATKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CSATKdll - !dll_export CSATKdll - call CSATK (icomp,t,kph,p,rho,csat,ierr,herr) - end -c ====================================================================== - subroutine DPTSATKdll (icomp,t,kph,p,rho,csat,dpt,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DPTSATKdll"::DPTSATKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DPTSATKdll - !dll_export DPTSATKdll - call DPTSATK (icomp,t,kph,p,rho,csat,dpt,ierr,herr) - end -c ====================================================================== - subroutine CV2PKdll (icomp,t,rho,cv2p,csat,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CV2PKdll"::CV2PKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CV2PKdll - !dll_export CV2PKdll - call CV2PK (icomp,t,rho,cv2p,csat,ierr,herr) - end -c ====================================================================== - subroutine PSATKdll (icomp,t,p,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PSATKdll"::PSATKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PSATKdll - !dll_export PSATKdll - call PSATK (icomp,t,p,ierr,herr) - end -c ====================================================================== - subroutine DLSATKdll (icomp,t,d,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DLSATKdll"::DLSATKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DLSATKdll - !dll_export DLSATKdll - call DLSATK (icomp,t,d,ierr,herr) - end -c ====================================================================== - subroutine DVSATKdll (icomp,t,d,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DVSATKdll"::DVSATKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DVSATKdll - !dll_export DVSATKdll - call DVSATK (icomp,t,d,ierr,herr) - end -c ====================================================================== - subroutine SPNDLdll (t,x,rhol,rhov,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SPNDLdll"::SPNDLdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SPNDLdll - !dll_export SPNDLdll - dimension x(ncmax) - call SPNDL (t,x,rhol,rhov,ierr,herr) - end -c ====================================================================== - subroutine TPRHOdll (t,p,x,j,i,rho,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TPRHOdll"::TPRHOdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TPRHOdll - !dll_export TPRHOdll - dimension x(ncmax) - call TPRHO (t,p,x,j,i,rho,ierr,herr) - end -c ====================================================================== - subroutine TPRHOPRdll (t,p,x,rho1,rho2) - implicit double precision (a-h,o-z) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TPRHOPRdll"::TPRHOPRdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TPRHOPRdll - !dll_export TPRHOPRdll - dimension x(ncmax) - call TPRHOPR (t,p,x,rho1,rho2) - end -c ====================================================================== - subroutine TPFLSHdll (t,p,z,D,Dl,Dv,x,y,q,e,h,s,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TPFLSHdll"::TPFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TPFLSHdll - !dll_export TPFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - if (t.gt.0.d0) - & call TPFLSH (t,p,z,D,Dl,Dv,x,y,q,e,h,s,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine TDFLSHdll (t,D,x,p,Dl,Dv,xl,xv,q,e,h,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TDFLSHdll"::TDFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TDFLSHdll - !dll_export TDFLSHdll - dimension x(ncmax),xl(ncmax),xv(ncmax) - call TDFLSH (t,D,x,p,Dl,Dv,xl,xv,q,e,h,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine PDFLSHdll (p,D,z,t,Dl,Dv,x,y,q,e,h,s,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PDFLSHdll"::PDFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PDFLSHdll - !dll_export PDFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call PDFLSH (p,D,z,t,Dl,Dv,x,y,q,e,h,s,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine PHFLSHdll (p,h,z,t,D,Dl,Dv,x,y,q,e,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PHFLSHdll"::PHFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PHFLSHdll - !dll_export PHFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call PHFLSH (p,h,z,t,D,Dl,Dv,x,y,q,e,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine PSFLSHdll (p,s,z,t,D,Dl,Dv,x,y,q,e,h,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PSFLSHdll"::PSFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PSFLSHdll - !dll_export PSFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call PSFLSH (p,s,z,t,D,Dl,Dv,x,y,q,e,h,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine PEFLSHdll (p,e,z,t,D,Dl,Dv,x,y,q,h,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PEFLSHdll"::PEFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PEFLSHdll - !dll_export PEFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call PEFLSH (p,e,z,t,D,Dl,Dv,x,y,q,h,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine THFLSHdll (t,h,z,kr,p,D,Dl,Dv,x,y,q,e,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_THFLSHdll"::THFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::THFLSHdll - !dll_export THFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call THFLSH (t,h,z,kr,p,D,Dl,Dv,x,y,q,e,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine TSFLSHdll (t,s,z,kr,p,D,Dl,Dv,x,y,q,e,h,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TSFLSHdll"::TSFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TSFLSHdll - !dll_export TSFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call TSFLSH (t,s,z,kr,p,D,Dl,Dv,x,y,q,e,h,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine TEFLSHdll (t,e,z,kr,p,D,Dl,Dv,x,y,q,h,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TEFLSHdll"::TEFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TEFLSHdll - !dll_export TEFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call TEFLSH (t,e,z,kr,p,D,Dl,Dv,x,y,q,h,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine DHFLSHdll (D,h,z,t,p,Dl,Dv,x,y,q,e,s,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHFLSHdll"::DHFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHFLSHdll - !dll_export DHFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call DHFLSH (D,h,z,t,p,Dl,Dv,x,y,q,e,s,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine DSFLSHdll (D,s,z,t,p,Dl,Dv,x,y,q,e,h,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DSFLSHdll"::DSFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DSFLSHdll - !dll_export DSFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call DSFLSH (D,s,z,t,p,Dl,Dv,x,y,q,e,h,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine DEFLSHdll (D,e,z,t,p,Dl,Dv,x,y,q,h,s,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DEFLSHdll"::DEFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DEFLSHdll - !dll_export DEFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call DEFLSH (D,e,z,t,p,Dl,Dv,x,y,q,h,s,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine HSFLSHdll (h,s,z,t,p,D,Dl,Dv,x,y,q,e,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_HSFLSHdll"::HSFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::HSFLSHdll - !dll_export HSFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call HSFLSH (h,s,z,t,p,D,Dl,Dv,x,y,q,e,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine ESFLSHdll (e,s,z,t,p,D,Dl,Dv,x,y,q,h,cv,cp,w,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ESFLSHdll"::ESFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ESFLSHdll - !dll_export ESFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call ESFLSH (e,s,z,t,p,D,Dl,Dv,x,y,q,h,cv,cp,w,ierr,herr) - end -c ====================================================================== - subroutine ABFL1dll (a,b,x,kph,ab,dmin,dmax,t,p,D,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*2 ab - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ABFL1dll"::ABFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ABFL1dll - !dll_export ABFL1dll - dimension x(ncmax) - call ABFL1 (a,b,x,kph,ab,dmin,dmax,t,p,D,ierr,herr) - end -c ====================================================================== - subroutine DBFL1dll (d,b,x,ab,t,p,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*2 ab - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DBFL1dll"::DBFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DBFL1dll - !dll_export DBFL1dll - dimension x(ncmax) - call DBFL1 (d,b,x,ab,t,p,ierr,herr) - end -c ====================================================================== - subroutine ABFL2dll (a,b,z,kq,ksat,ab, - & tbub,tdew,pbub,pdew,Dlbub,Dvdew,ybub,xdew, - & t,p,Dl,Dv,x,y,q,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*2 ab - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_ABFL2dll"::ABFL2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::ABFL2dll - !dll_export ABFL2dll - dimension z(ncmax),ybub(ncmax),xdew(ncmax),x(ncmax),y(ncmax) - call ABFL2 (a,b,z,kq,ksat,ab, - & tbub,tdew,pbub,pdew,Dlbub,Dvdew,ybub,xdew, - & t,p,Dl,Dv,x,y,q,ierr,herr) - end -c ====================================================================== - subroutine DBFL2dll (d,b,z,kq,ab,t,p,Dl,Dv,x,y,q,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*2 ab - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DBFL2dll"::DBFL2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DBFL2dll - !dll_export DBFL2dll - dimension z(ncmax),x(ncmax),y(ncmax) - call DBFL2 (d,b,z,kq,ab,t,p,Dl,Dv,x,y,q,ierr,herr) - end -c ====================================================================== - subroutine TQFLSHdll (t,q,z,kq,p,D,Dl,Dv,x,y,e,h,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TQFLSHdll"::TQFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TQFLSHdll - !dll_export TQFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call TQFLSH (t,q,z,kq,p,D,Dl,Dv,x,y,e,h,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine PQFLSHdll (p,q,z,kq,t,D,Dl,Dv,x,y,e,h,s,cv,cp,w,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PQFLSHdll"::PQFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PQFLSHdll - !dll_export PQFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call PQFLSH (p,q,z,kq,t,D,Dl,Dv,x,y,e,h,s,cv,cp,w,i,herr) - end -c ====================================================================== - subroutine CSTARdll (t,p,v,x,cs,ts,Ds,ps,ws,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CSTARdll"::CSTARdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CSTARdll - !dll_export CSTARdll - dimension x(ncmax) - call CSTAR (t,p,v,x,cs,ts,Ds,ps,ws,ierr,herr) - end -c ====================================================================== - subroutine CCRITdll (t,p,v,x,cs,ts,Ds,ps,ws,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CCRITdll"::CCRITdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CCRITdll - !dll_export CCRITdll - dimension x(ncmax) - call CSTAR (t,p,v,x,cs,ts,Ds,ps,ws,ierr,herr) - end -c ====================================================================== - subroutine FPVdll (t,rho,p,x,f) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_FPVdll"::FPVdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::FPVdll - !dll_export FPVdll - dimension x(ncmax) - call FPV (t,rho,p,x,f) - end -c ====================================================================== - subroutine CP0dll (t,x,cp) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_CP0dll"::CP0dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::CP0dll - !dll_export CP0dll - dimension x(ncmax) - cp=CP0(t,x) - end -c ====================================================================== - subroutine TRNPRPdll (t,rho,x,eta,tcx,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TRNPRPdll"::TRNPRPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TRNPRPdll - !dll_export TRNPRPdll - dimension x(ncmax) - call TRNPRP (t,rho,x,eta,tcx,ierr,herr) - if (tcx.gt.1.d50) tcx=0 !Avoid NaN (not a number) - if (eta.gt.1.d50) eta=0 !Avoid NaN (not a number) - end -c ====================================================================== - subroutine INFOdll (icomp,wmm,ttrp,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas) - implicit double precision (a-h,o-z) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_INFOdll"::INFOdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::INFOdll - !dll_export INFOdll - call INFO (icomp,wmm,ttrp,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas) - end -c ====================================================================== - subroutine NAMEdll (icomp,hname,hn80,hcas) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*12 hcas,hname - character*80 hn80 -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_NAMEdll"::NAMEdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::NAMEdll - !dll_export NAMEdll - call NAME (icomp,hname,hn80,hcas) - end -c ====================================================================== - subroutine XMASSdll (xmol,xkg,wmix) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_XMASSdll"::XMASSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::XMASSdll - !dll_export XMASSdll - dimension xmol(ncmax),xkg(ncmax) - call XMASS (xmol,xkg,wmix) - end -c ====================================================================== - subroutine XMOLEdll (xkg,xmol,wmix) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_XMOLEdll"::XMOLEdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::XMOLEdll - !dll_export XMOLEdll - dimension xmol(ncmax),xkg(ncmax) - call XMOLE (xkg,xmol,wmix) - end -c ====================================================================== - subroutine LIMITXdll (htyp,t,D,p,x,tmin,tmax,Dmax,pmax,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*3 htyp - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_LIMITXdll"::LIMITXdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::LIMITXdll - !dll_export LIMITXdll - dimension x(ncmax) - call LIMITX (htyp,t,D,p,x,tmin,tmax,Dmax,pmax,ierr,herr) - end -c ====================================================================== - subroutine LIMITKdll (htyp,icomp,t,D,p,tmin,tmax,Dmax,pmax,i,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*3 htyp - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_LIMITKdll"::LIMITKdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::LIMITKdll - !dll_export LIMITKdll - call LIMITK (htyp,icomp,t,D,p,tmin,tmax,Dmax,pmax,i,herr) - end -c ====================================================================== - subroutine LIMITSdll (htyp,x,tmin,tmax,Dmax,pmax) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*3 htyp -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_LIMITSdll"::LIMITSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::LIMITSdll - !dll_export LIMITSdll - dimension x(ncmax) - call LIMITS (htyp,x,tmin,tmax,Dmax,pmax) - end -c ====================================================================== - subroutine QMASSdll (qmol,xl,xv,qkg,xlkg,xvkg,wliq,wvap,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_QMASSdll"::QMASSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::QMASSdll - !dll_export QMASSdll - dimension xl(ncmax),xv(ncmax),xlkg(ncmax),xvkg(ncmax) - call QMASS (qmol,xl,xv,qkg,xlkg,xvkg,wliq,wvap,ierr,herr) - end -c ====================================================================== - subroutine QMOLEdll (qkg,xlkg,xvkg,qmol,xl,xv,wliq,wvap,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_QMOLEdll"::QMOLEdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::QMOLEdll - !dll_export QMOLEdll - dimension xl(ncmax),xv(ncmax),xlkg(ncmax),xvkg(ncmax) - call QMOLE (qkg,xlkg,xvkg,qmol,xl,xv,wliq,wvap,ierr,herr) - end -c ====================================================================== - subroutine WMOLdll (x, wm) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_WMOLdll"::WMOLdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::WMOLdll - !dll_export WMOLdll - dimension x(ncmax) - wm=WMOL(x) - end -c ====================================================================== - subroutine DIELECdll (t,rho,x,de) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DIELECdll"::DIELECdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DIELECdll - !dll_export DIELECdll - dimension x(ncmax) - call DIELEC (t,rho,x,de) - end -c ====================================================================== - subroutine SURFTdll (t,rho,x,sigma,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SURFTdll"::SURFTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SURFTdll - !dll_export SURFTdll - dimension x(ncmax) - call SURFT (t,rho,x,sigma,ierr,herr) - end -c ====================================================================== - subroutine EXCESSdll (t,p,x,kph,rho,vE,eE,hE,sE,aE,gE,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_EXCESSdll"::EXCESSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::EXCESSdll - !dll_export EXCESSdll - dimension x(ncmax) - call EXCESS (t,p,x,kph,rho,vE,eE,hE,sE,aE,gE,ierr,herr) - end -c ====================================================================== - subroutine SURTENdll (t,rhol,rhov,xl,xv,sigma,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SURTENdll"::SURTENdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SURTENdll - !dll_export SURTENdll - dimension xl(ncmax),xv(ncmax) - call SURTEN (t,rhol,rhov,xl,xv,sigma,ierr,herr) - end -c ====================================================================== - subroutine PDFL1dll (p,rho,x,t,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PDFL1dll"::PDFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PDFL1dll - !dll_export PDFL1dll - dimension x(ncmax) - call PDFL1 (p,rho,x,t,ierr,herr) - end -c ====================================================================== - subroutine PHFL1dll (p,h,x,kph,t,D,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PHFL1dll"::PHFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PHFL1dll - !dll_export PHFL1dll - dimension x(ncmax) - call PHFL1 (p,h,x,kph,t,D,ierr,herr) - end -c ====================================================================== - subroutine PSFL1dll (p,s,x,kph,t,D,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PSFL1dll"::PSFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PSFL1dll - !dll_export PSFL1dll - dimension x(ncmax) - call PSFL1 (p,s,x,kph,t,D,ierr,herr) - end -c ====================================================================== - subroutine SETKTVdll (icomp,jcomp,hmodij,fij,hfmix,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (nmxpar=6) - character*3 hmodij - character*255 hfmix,herr - dimension fij(nmxpar) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETKTVdll"::SETKTVdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETKTVdll - !dll_export SETKTVdll - call SETKTV (icomp,jcomp,hmodij,fij,hfmix,ierr,herr) - end -c ====================================================================== - subroutine GETKTVdll (icomp,jcomp,hmodij,fij,hfmix,hfij2,hbinp, - & hmxrul) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (nmxpar=6) - character*3 hmodij - character*8 hfij(nmxpar) - character*255 hfmix,hmxrul,hbinp,hfij2 - dimension fij(nmxpar) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_GETKTVdll"::GETKTVdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::GETKTVdll - !dll_export GETKTVdll - call GETKTV (icomp,jcomp,hmodij,fij,hfmix,hfij,hbinp,hmxrul) - hfij2=hfij(1)//hfij(2)//hfij(3)//hfij(4)//hfij(5)//hfij(6) - end -c ====================================================================== - subroutine GETFIJdll (hmodij,fij,hfij2,hmxrul) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (nmxpar=6) - character*3 hmodij - character*8 hfij(nmxpar) - character*255 hmxrul,hfij2 - dimension fij(nmxpar) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_GETFIJdll"::GETFIJdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::GETFIJdll - !dll_export GETFIJdll - call GETFIJ (hmodij,fij,hfij,hmxrul) - hfij2=hfij(1)//hfij(2)//hfij(3)//hfij(4)//hfij(5)//hfij(6) - end -c ====================================================================== - subroutine MELTTdll (t,x,p,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_MELTTdll"::MELTTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::MELTTdll - !dll_export MELTTdll - dimension x(ncmax) - call MELTT (t,x,p,ierr,herr) - end -c ====================================================================== - subroutine MLTH2Odll (t,p1,p2) - implicit double precision (a-h,o-z) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_MLTH2Odll"::MLTH2Odll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::MLTH2Odll - !dll_export MLTH2Odll - call MLTH2O (t,p1,p2) - end -c ====================================================================== - subroutine MELTPdll (p,x,t,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_MELTPdll"::MELTPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::MELTPdll - !dll_export MELTPdll - dimension x(ncmax) - call MELTP (p,x,t,ierr,herr) - end -c ====================================================================== - subroutine SUBLTdll (t,x,p,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SUBLTdll"::SUBLTdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SUBLTdll - !dll_export SUBLTdll - dimension x(ncmax) - call SUBLT (t,x,p,ierr,herr) - end -c ====================================================================== - subroutine SUBLPdll (p,x,t,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SUBLPdll"::SUBLPdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SUBLPdll - !dll_export SUBLPdll - dimension x(ncmax) - call SUBLP (p,x,t,ierr,herr) - end -c ====================================================================== - subroutine PREOSdll (i) - implicit integer (i-n) -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_PREOSdll"::PREOSdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::PREOSdll - !dll_export PREOSdll - call PREOS (i) - end -c ====================================================================== - subroutine SETAGAdll (ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_SETAGAdll"::SETAGAdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::SETAGAdll - !dll_export SETAGAdll - call SETAGA (ierr,herr) - end -c ====================================================================== - subroutine GERG04dll (nc,iflag,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_GERG04dll"::GERG04dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::GERG04dll - !dll_export GERG04dll - call GERG04 (nc,iflag,ierr,herr) - end -c ====================================================================== - subroutine DOTFILLdll (x,ptest,filrat,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DOTFILLdll"::DOTFILLdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DOTFILLdll - !dll_export DOTFILLdll - dimension x(ncmax) - call DOTFILL (x,ptest,filrat,ierr,herr) - end diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl b/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl new file mode 100644 index 0000000..edc83be --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl @@ -0,0 +1,68 @@ +c ====================================================================== +c Adding new routines used in the Modelica interface. +c subroutine DHFL1 (rho,h,x,t,ierr,herr) +c subroutine DHFL2 (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) +c subroutine DSFL1 (rho,s,x,t,ierr,herr) +c subroutine DSFL2 (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) +c subroutine TPFL2 (t,p,z,Dl,Dv,x,y,q,ierr,herr) +c ====================================================================== + subroutine DHFL1dll (rho,h,x,t,ierr,herr) + implicit double precision (a-h,o-z) + implicit integer (i-n) + parameter (ncmax=20) + character*255 herr +cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHFLSHdll"::DHFLSHdll +cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHFLSHdll + !dll_export DHFLSHdll + dimension x(ncmax) + call DHFL1 (rho,h,x,t,ierr,herr) + end +c ====================================================================== + subroutine DHFL2dll (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) + implicit double precision (a-h,o-z) + implicit integer (i-n) + parameter (ncmax=20) + character*255 herr +cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHFLSHdll"::DHFLSHdll +cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHFLSHdll + !dll_export DHFLSHdll + dimension z(ncmax),x(ncmax),y(ncmax) + call DHFL2 (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) + end +c ====================================================================== + subroutine DSFL1dll (rho,s,x,t,ierr,herr) + implicit double precision (a-h,o-z) + implicit integer (i-n) + parameter (ncmax=20) + character*255 herr +cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DSFL1dll"::DSFL1dll +cDEC$ ATTRIBUTES STDCALL, REFERENCE::DSFL1dll + !dll_export DSFL1dll + dimension x(ncmax) + call DSFL1 (rho,s,x,t,ierr,herr) + end +c ====================================================================== + subroutine DSFL2dll (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) + implicit double precision (a-h,o-z) + implicit integer (i-n) + parameter (ncmax=20) + character*255 herr +cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DSFL2dll"::DSFL2dll +cDEC$ ATTRIBUTES STDCALL, REFERENCE::DSFL2dll + !dll_export DSFL2dll + dimension z(ncmax),x(ncmax),y(ncmax) + call DSFL2 (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) + end +c ====================================================================== + subroutine TPFL2dll (t,p,z,Dl,Dv,x,y,q,ierr,herr) + implicit double precision (a-h,o-z) + implicit integer (i-n) + parameter (ncmax=20) + character*255 herr +cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TPFL2dll"::TPFL2dll +cDEC$ ATTRIBUTES STDCALL, REFERENCE::TPFL2dll + !dll_export TPFL2dll + dimension z(ncmax),x(ncmax),y(ncmax) + call TPFL2 (t,p,z,Dl,Dv,x,y,q,ierr,herr) + end +c ====================================================================== \ No newline at end of file From 19adf5863770c6e1b6d58fd9551c3c57b0b85208 Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 19 Sep 2012 07:27:18 -0700 Subject: [PATCH 03/57] 2012:09:19 16:26 - Included instructions to change the lowercase library name to uppercase. Still no success with Dymola. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 54 +++++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index d951e9d..0026793 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -5,6 +5,13 @@ # Copyright : Use and modify at your own risk. # Description : Makefile for Refprop from Fortran and C++ tests. # ============================================================================ +# The installation procedure should be as follows: +# 1) make libheader library +# 2) sudo make installlib +# 3) make wrapheader wrapper +# 4) sudo make installwrap +# 5) sudo make fixit +# ============================================================================ # used for the output THENAME =refprop @@ -81,18 +88,55 @@ LIBOBJECTFILES = \ # Link all files to places recognised by the system. ########################################################### .PHONY : install -install : all +install : installlib installwrap + +.PHONY : installlib +installlib : libheader library ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : installwrap +installwrap: wrapheader wrapper ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) -.PHONY : all -all : library libheader wrapper wrapheader +.PHONY : uninstall +uninstall : + $(RM) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(RM) $(LIBINST)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) + $(RM) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) + $(RM) $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + $(RM) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) + $(RM) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : purge +purge : + $(RM) $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) + $(RM) $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) + $(RM) $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + +.PHONY : fixit +fixit : install + ln -sf $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + ln -sf /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) /usr/lib/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + +.PHONY : unfixit +unfixit : + $(RM) $(LIBINST)/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + $(RM) /usr/lib/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + +.PHONY : removeall +removeall : uninstall purge unfixit + +#.PHONY : all +#all : install fixit ########################################################### # Compile the wrapper class and its tests. @@ -104,12 +148,12 @@ $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION): $(THEWRAPPER)$(HEADEREXTENSION) .PHONY : wrapper wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) -$(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o library libheader +$(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader library $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) .PHONY : test test : $(THETEST) -$(THETEST) : $(THETEST).o wrapper wrapheader +$(THETEST) : $(THETEST).o wrapheader wrapper $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o -l$(THEWRAPPER) ########################################################### From 674452c40ffb1cef514387949fc57d5d848b9d88 Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 20 Sep 2012 06:23:45 -0700 Subject: [PATCH 04/57] 2012:09:20 15:22 - The Modelica examples work, both for pure fluids and mixtures. However, the C++ code in the wrapper could be a little cleaner... --- .../Version 0.5_linux/refprop_wrapper.cpp | 24 ++++++++++++-- .../Version 0.5_linux/refpropwrappertest.cpp | 31 +++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp index 31def50..2fc02d6 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp @@ -60,6 +60,7 @@ static int const GB_exitError = 2 ; static int const GB_exitFatal = 3 ; static int const GB_exitInternal = 4 ; + char *str_replace(char *str, char *search, char *replace, long *count) { int i,n_ret; int newlen = strlen(replace); @@ -583,7 +584,7 @@ OUTPUT //--------------------------------------------------------------------------- -double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ /*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) INPUT: what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function @@ -611,17 +612,31 @@ OUTPUT return 0; } + if (DEBUGMODE) printf("\nFunction init_REFPROP was called\n"); //CALCULATE MOLAR MASS // WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); WMOLdll(x,wm); // sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); + if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); + wm /= 1000; //g/mol -> kg/mol + if (DEBUGMODE) printf("\nwm converted.\n"); - //identify and assign passed state variables - statevar[0] = tolower(statevar[0]); + if (DEBUGMODE) printf("\statevar is %s \n",statevar_in); + //identify and assign passed state variables + // char tmpstr[1]; + // strcpy(tmpstr,statevar[0]); + // statevar = toLowerCase(tmpstr); + //statevar[0] = tolower(statevar[0]); + char statevar[1]; + statevar[0] = tolower(statevar_in[0]); + if (DEBUGMODE) printf("\nstatevar lowercase.\n"); if (statevar[0]!='\0'){ +// if (strcmp(statevar[0],"")){ +// if (statevar[0] != NULL){ + if (DEBUGMODE) printf("\nentering statevar switch.\n"); switch(statevar[0]){ case 'p': p = statevarval/1000; //Pa->kPa @@ -644,6 +659,9 @@ OUTPUT return 0; } } + + if (DEBUGMODE) printf("\nstatevar checked.\n"); + double xliq[ncmax],xvap[ncmax],f[ncmax]; long j=2,kr; diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp index 377b89e..9fb00fc 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp @@ -68,5 +68,36 @@ int main(int argc, char* argv[]){ printf("Xliq[%i]=%f\t",ii+1, props[16+ii]); printf("Xvap[%i]=%f\n",ii+1, props[16+nX+ii]); } + + // INPUT: + // what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + // statevar: string of 1 variable out of p,T,h,s,d + // fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + // statevarval: values of the variable specified in statevar + // x: array containing the mass fractions of the components of the mixture + // REFPROP_PATH: string defining the path of the refprop.dll + // OUTPUT + // return value: value of variable specified by the input variable what + // props: Array containing all calculated values + // errormsg: string containing error message + // + char what[255]; + strcpy(what, "T"); + char statevar[255]; + strcpy(statevar, "p"); + // fluidname defined above + //strcpy(fluidname,argv[2]); + strcpy(fluidname,"BUTANE"); + //props is defined + double statevarval = 1e5; // 1 bar + // x is defined + char REFPROP_PATH[255]; + strcpy(REFPROP_PATH,argv[5]); + + double T; + T = satprops_REFPROP (what, statevar, fluidname, props, statevarval, x, REFPROP_PATH, errormsg, DEBUG); + printf("Saturation conditions for %s\t",fluidname); + printf("Saturation temperature =%f\t",T); + return 0; } From 7c61a6a5b4fc90fc452241a062b55af973d055a8 Mon Sep 17 00:00:00 2001 From: jowr Date: Fri, 21 Sep 2012 01:22:39 -0700 Subject: [PATCH 05/57] 2012:09:21 10:22 - Added text for the Linux version to the readme.txt. --- readme.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 5444151..5d4435f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,24 @@ +Welcome to REFPROP2Modelica! + +This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the "Media" framework inside Modelica. It has only been tested with Dymola sofar. + +For Windows, please follow these instructions 1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". 2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) 3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ + +For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. +1. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. +2. Call "make libheader library" and "sudo make installlib" to compile and install refprop. +3. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. + +For both versions, the last step is the same: + 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). Make sure you mask the backslashes. It should look something like - constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\\"; + constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; + or + constant String REFPROP_PATH = "/home/user/Refprop/"; + + +Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. \ No newline at end of file From 4ca40d625722703b5673ecc3aab472692bd27666 Mon Sep 17 00:00:00 2001 From: jowr Date: Mon, 1 Oct 2012 15:57:58 -0700 Subject: [PATCH 06/57] 2012:10:01 00:09 - Changed header file for increased portability, started to use POCO library in test file. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 24 +- .../Version 0.5_linux/refprop_wrapper.cpp | 5 +- .../Version 0.5_linux/src/librefprop.h | 331 -------- .../Version 0.5_linux/src/refprop-ftn.cpp | 34 +- .../Version 0.5_linux/src/refprop_lib.h | 795 ++++++++++++++++++ 5 files changed, 848 insertions(+), 341 deletions(-) delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/librefprop.h create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index 0026793..c90d5d6 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -28,12 +28,13 @@ LIBINST =$(DYMDIR)/bin/lib HEADINST =$(DYMDIR)/source BINDIR =. +OPTFLAGS = -O3 -ffast-math# -ffloat-store # optimisation, remove for debugging ########################################################### # Change these lines if you are using a different Fortran # compiler or if you would like to use other flags. ########################################################### FC =gfortran -FFLAGS =-Wall -ff2c -pedantic -ffloat-store# -fbounds-check +FFLAGS =$(OPTFLAGS) -Wall -pedantic# -ff2c -fbounds-check FLINKFLAGS =$(FFLAGS) ########################################################### @@ -41,7 +42,7 @@ FLINKFLAGS =$(FFLAGS) # compiler or if you would like to use other flags. ########################################################### CPPC =g++ -CPPFLAGS =-O2 -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 +CPPFLAGS =$(OPTFLAGS) -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 ########################################################### # Change these lines if you have other needs regarding @@ -53,7 +54,7 @@ LIBFILE =PASS_FTN_LIN DYNAMICLIBRARYEXTENSION =.so STATICLIBRARYEXTENSION =.a #ar -cvq $(LIBRARY)$(STATICLIBRARYEXTENSION) $(OBJECTFILES) -HEADERFILE =lib$(THENAME) +HEADERFILE =$(THENAME)_lib HEADEREXTENSION =.h ### List of files to compile LIBOBJECTFILES = \ @@ -116,7 +117,7 @@ uninstall : $(RM) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) .PHONY : purge -purge : +purge : cleanlib $(RM) $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(RM) $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) $(RM) $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) @@ -135,8 +136,13 @@ unfixit : .PHONY : removeall removeall : uninstall purge unfixit -#.PHONY : all -#all : install fixit +.PHONY : all +all : + make libheader library + sudo make installlib + make wrapheader wrapper + sudo make installwrap + sudo make fixit ########################################################### # Compile the wrapper class and its tests. @@ -198,6 +204,10 @@ src/%.o : src/%.cpp .PHONY: clean clean: $(RM) **.o **.so **.mod $(BINDIR)/RP-ftn src/$(LIBFILE).FOR $(THETEST) + +.PHONY : cleanlib +cleanlib : + $(RM) $(LIBDIR)/fortran/**.o ########################################################### # Compile a simple example to illustrate the connection @@ -208,7 +218,7 @@ clean: RP-ftn : $(BINDIR)/RP-ftn $(BINDIR)/RP-ftn : src/refprop-ftn.cpp libheader library $(CPPC) $(CPPFLAGS) -o src/refprop-ftn.o -c src/refprop-ftn.cpp - $(FC) $(FLINKFLAGS) -o $(BINDIR)/RP-ftn src/refprop-ftn.o -l$(THENAME) + $(FC) $(FLINKFLAGS) -o $(BINDIR)/RP-ftn src/refprop-ftn.o -l$(THENAME) -lPocoFoundation .PHONY : f2f f2f : $(BINDIR)/f2f diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp index 2fc02d6..74c03ed 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp @@ -12,7 +12,8 @@ GFZ German Research Centre for Geosciences Telegrafenberg, D-14473 Potsdam - Modified for Linux in 2012 by + Modified for portability to Linux and + introduction of POCO library in 2012 by Jorrit Wronski (jowr@mek.dtu.dk) DTU Mechanical Engineering @@ -32,7 +33,7 @@ #else // assuming Linux system # include # include -# include +# include //# include // dlopen etc # include // tolower etc #endif diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/librefprop.h b/_REFPROP-Wrapper/Version 0.5_linux/src/librefprop.h deleted file mode 100644 index 01e909d..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/librefprop.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef REFPROP_H -#define REFPROP_H -// -#include -#ifdef _CRAY -# include -# define RPVersion RPVERSION -# define SETPATHdll SETPATHDLL -# define ABFL1dll ABFL1DLL -# define ABFL2dll ABFL2DLL -# define ACTVYdll ACTVYDLL -# define AGdll AGDLL -# define CCRITdll CCRITDLL -# define CP0dll CP0DLL -# define CRITPdll CRITPDLL -# define CSATKdll CSATKDLL -# define CV2PKdll CV2PKDLL -# define CVCPKdll CVCPKDLL -# define CVCPdll CVCPDLL -# define DBDTdll DBDTDLL -# define DBFL1dll DBFL1DLL -# define DBFL2dll DBFL2DLL -# define DDDPdll DDDPDLL -# define DDDTdll DDDTDLL -# define DEFLSHdll DEFLSHDLL -# define DHD1dll DHD1DLL -# define DHFL1dll DHFL1DLL -# define DHFL2dll DHFL2DLL -# define DHFLSHdll DHFLSHDLL -# define DIELECdll DIELECDLL -# define DOTFILLdll DOTFILLDLL -# define DPDD2dll DPDD2DLL -# define DPDDKdll DPDDKDLL -# define DPDDdll DPDDDLL -# define DPDTKdll DPDTKDLL -# define DPDTdll DPDTDLL -# define DPTSATKdll DPTSATKDLL -# define DSFLSHdll DSFLSHDLL -# define DSFL1dll DSFL1DLL -# define DSFL2dll DSFL2DLL -# define ENTHALdll ENTHALDLL -# define ENTROdll ENTRODLL -# define ESFLSHdll ESFLSHDLL -# define FGCTYdll FGCTYDLL -# define FPVdll FPVDLL -# define GERG04dll GERG04DLL -# define GETFIJdll GETFIJDLL -# define GETKTVdll GETKTVDLL -# define GIBBSdll GIBBSDLL -# define HSFLSHdll HSFLSHDLL -# define INFOdll INFODLL -# define LIMITKdll LIMITKDLL -# define LIMITSdll LIMITSDLL -# define LIMITXdll LIMITXDLL -# define MELTPdll MELTPDLL -# define MELTTdll MELTTDLL -# define MLTH2Odll MLTH2ODLL -# define NAMEdll NAMEDLL -# define PDFL1dll PDFL1DLL -# define PDFLSHdll PDFLSHDLL -# define PEFLSHdll PEFLSHDLL -# define PHFL1dll PHFL1DLL -# define PHFLSHdll PHFLSHDLL -# define PQFLSHdll PQFLSHDLL -# define PREOSdll PREOSDLL -# define PRESSdll PRESSDLL -# define PSFL1dll PSFL1DLL -# define PSFLSHdll PSFLSHDLL -# define PUREFLDdll PUREFLDDLL -# define QMASSdll QMASSDLL -# define QMOLEdll QMOLEDLL -# define SATDdll SATDDLL -# define SATEdll SATEDLL -# define SATHdll SATHDLL -# define SATPdll SATPDLL -# define SATSdll SATSDLL -# define SATTdll SATTDLL -# define SETAGAdll SETAGADLL -# define SETKTVdll SETKTVDLL -# define SETMIXdll SETMIXDLL -# define SETMODdll SETMODDLL -# define SETREFdll SETREFDLL -# define SETUPdll SETUPDLL -# define SPECGRdll SPECGRDLL -# define SUBLPdll SUBLPDLL -# define SUBLTdll SUBLTDLL -# define SURFTdll SURFTDLL -# define SURTENdll SURTENDLL -# define TDFLSHdll TDFLSHDLL -# define TEFLSHdll TEFLSHDLL -# define THERM0dll THERM0DLL -# define THERM2dll THERM2DLL -# define THERM3dll THERM3DLL -# define THERMdll THERMDLL -# define THFLSHdll THFLSHDLL -# define TPFLSHdll TPFLSHDLL -# define TPFL2dll TPFL2DLL -# define TPRHOdll TPRHODLL -# define TQFLSHdll TQFLSHDLL -# define TRNPRPdll TRNPRPDLL -# define TSFLSHdll TSFLSHDLL -# define VIRBdll VIRBDLL -# define VIRCdll VIRCDLL -# define WMOLdll WMOLDLL -# define XMASSdll XMASSDLL -# define XMOLEdll XMOLEdll -#else -# if !defined(_AIX) && !defined(__hpux) -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -# define SPECGRdll specgrdll_ -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -# endif -# define _fcd char * -# define _cptofcd(a,b) (a) -# define _fcdlen(a) strlen(a) -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - // extra function for setup - void RPVersion ( char* ); - void SETPATHdll( const char* ); - // - void ABFL1dll(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void ABFL2dll(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - void ACTVYdll(double &,double &,double *,double &); - void AGdll(double &,double &,double *,double &,double &); - void CCRITdll(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); - void CP0dll(double &,double *,double &); - void CRITPdll(double *,double &,double &,double &,long &,char*,long ); - void CSATKdll(long &,double &,long &,double &,double &,double &,long &,char*,long ); - void CV2PKdll(long &,double &,double &,double &,double &,long &,char*,long ); - void CVCPKdll(long &,double &,double &,double &,double &); - void CVCPdll(double &,double &,double *,double &,double &); - void DBDTdll(double &,double *,double &); - void DBFL1dll(double &,double &,double *,double &,double &,double &,long &,char*,long ); - void DBFL2dll(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - void DDDPdll(double &,double &,double *,double &); - void DDDTdll(double &,double &,double *,double &); - void DEFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void DHD1dll(double &,double &,double *,double &,double &,double &,double &,double &,double &); - void DHFL1dll(double &,double &,double *,double &,long &,char*,long );//added by henning francke - void DHFL2dll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke - void DHFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void DIELECdll(double &,double &,double *,double &); - void DOTFILLdll(long &,double *,double &,double &,long &,char*,long ); - void DPDD2dll(double &,double &,double *,double &); - void DPDDKdll(long &,double &,double &,double &); - void DPDDdll(double &,double &,double *,double &); - void DPDTKdll(long &,double &,double &,double &); - void DPDTdll(double &,double &,double *,double &); - void DPTSATKdll(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); - void DSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void DSFL1dll(double &,double &,double *,double &,long &,char*,long );//added by henning francke - void DSFL2dll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke - void ENTHALdll(double &,double &,double *,double &); - void ENTROdll(double &,double &,double *,double &); - void ESFLSHdll(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - void FGCTYdll(double &,double &,double *,double *); - void FPVdll(double &,double &,double &,double *,double &); - void GERG04dll(long &,long &,long &,char*,long ); - void GETFIJdll(char*,double *,char*,char*,long ,long ,long ); - void GETKTVdll(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); - void GIBBSdll(double &,double &,double *,double &,double &); - void HSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - void INFOdll(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - void LIMITKdll(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); - void LIMITSdll(char*,double *,double &,double &,double &,double &,long ); - void LIMITXdll(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - void MELTPdll(double &,double *,double &,long &,char*,long ); - void MELTTdll(double &,double *,double &,long &,char*,long ); - void MLTH2Odll(double &,double &,double &); - void NAMEdll(long &,char*,char*,char*,long ,long ,long ); - void PDFL1dll(double &,double &,double *,double &,long &,char*,long ); - void PDFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void PEFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void PHFL1dll(double &,double &,double *,long &,double &,double &,long &,char*,long ); - void PHFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void PQFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void PREOSdll(long &); - void PRESSdll(double &,double &,double *,double &); - void PSFL1dll(double &,double &,double *,long &,double &,double &,long &,char*,long ); - void PSFLSHdll(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void PUREFLDdll(long &); - void QMASSdll(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - void QMOLEdll(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - void SATDdll(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); - void SATEdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - void SATHdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - void SATPdll(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - void SATSdll(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - void SATTdll(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - void SETAGAdll(long &,char*,long ); - void SETKTVdll(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); - void SETMIXdll(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); - void SETMODdll(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - void SETREFdll(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - //void SETUPdll(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - void SETUPdll(long &,char*,char*,char*,long &,char*); - void SPECGRdll(double &,double &,double &,double &); - void SUBLPdll(double &,double *,double &,long &,char*,long ); - void SUBLTdll(double &,double *,double &,long &,char*,long ); - void SURFTdll(double &,double &,double *,double &,long &,char*,long ); - void SURTENdll(double &,double &,double &,double *,double *,double &,long &,char*,long ); - void TDFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void TEFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void THERM0dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); - void THERM2dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - void THERM3dll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - void THERMdll(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); - void THFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void TPFLSHdll(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void TPFL2dll(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long );//added by henning francke - void TPRHOdll(double &,double &,double *,long &,long &,double &,long &,char*,long ); - void TQFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void TRNPRPdll(double &,double &,double *,double &,double &,long &,char*,long ); - void TSFLSHdll(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - void VIRBdll(double &,double *,double &); - void VIRCdll(double &,double *,double &); - void WMOLdll(double *,double &); - void XMASSdll(double *,double *,double &); - void XMOLEdll(double *,double *,double &); -#ifdef __cplusplus -} // extern "C" -#endif -// REFPROP_H -#endif -// routines used in henning francke's wrapper -// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, -// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD -// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 -// diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp index 5441064..cef9502 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp @@ -14,7 +14,7 @@ #include #include /* EXIT_SUCCESS */ #include /* strlen, memset, memcpy, memchr */ -#include /* refprop header file */ +#include /* refprop header file */ #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 @@ -29,10 +29,24 @@ #define numparams 72 #define maxcoefs 50 +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) + +//#define TEST_FUNC test_func +//#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) + +//#define TEST_FUNC test_func // done in header +#define RPVersion_NAME FUNCTION_NAME(RPVersion) + + void newline() { printf("%s","\n"); } +#include "Poco/SharedLibrary.h" +using Poco::SharedLibrary; int main(int argc, char* argv[]) { static long i,ierr,info_index; @@ -47,6 +61,24 @@ int main(int argc, char* argv[]) { newline(); +// HINSTANCE dll = LoadLibrary("mydll.dll"); +// +// func_t * f = (func_t *)GetProcAddress(dll, "func"); +// +// f(1, 1.2f); + +// std::string path("/usr/lib/librefprop"); + std::string path("librefprop"); + path.append(SharedLibrary::suffix()); // adds ".dll" or ".so" + SharedLibrary library(path); // will also load the library + //RPVersion_t * func = (RPVersion_t *) library.getSymbol("rpversion_"); + RPVersion_t * func = (RPVersion_t *) library.getSymbol(RPVersion_NAME); + func(v); + printf("func(v) returned v = %s\n", v); + library.unload(); + + newline(); + RPVersion(v); printf("RPVersion(v) returned v = %s\n", v); diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h new file mode 100644 index 0000000..91e0796 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h @@ -0,0 +1,795 @@ +#ifndef REFPROP_H +#define REFPROP_H +// +#include + +// Define data types that match the Fortran definitions. This is also +// a possible starting point to introduce platform independence. +// Partly taken from: http://arnholm.org/software/cppf77/cppf77.htm#Section5 +// An issue with characters still needs to be solved. +//#include +// The other data types can be handled: +typedef long INTEGER; +typedef float REAL; +typedef double DOUBLE_PRECISION; +typedef int LOGICAL; + +#if defined(WIN32) || defined(_WIN32) +//# define LIBRARY_API __declspec(dllexport) +# define LIBRARY_API __stdcall +#else +# define LIBRARY_API +#ifdef _CRAY +# include +# define RPVersion RPVERSION +# define SETPATHdll SETPATHDLL +# define ABFL1dll ABFL1DLL +# define ABFL2dll ABFL2DLL +# define ACTVYdll ACTVYDLL +# define AGdll AGDLL +# define CCRITdll CCRITDLL +# define CP0dll CP0DLL +# define CRITPdll CRITPDLL +# define CSATKdll CSATKDLL +# define CV2PKdll CV2PKDLL +# define CVCPKdll CVCPKDLL +# define CVCPdll CVCPDLL +# define DBDTdll DBDTDLL +# define DBFL1dll DBFL1DLL +# define DBFL2dll DBFL2DLL +# define DDDPdll DDDPDLL +# define DDDTdll DDDTDLL +# define DEFLSHdll DEFLSHDLL +# define DHD1dll DHD1DLL +# define DHFL1dll DHFL1DLL +# define DHFL2dll DHFL2DLL +# define DHFLSHdll DHFLSHDLL +# define DIELECdll DIELECDLL +# define DOTFILLdll DOTFILLDLL +# define DPDD2dll DPDD2DLL +# define DPDDKdll DPDDKDLL +# define DPDDdll DPDDDLL +# define DPDTKdll DPDTKDLL +# define DPDTdll DPDTDLL +# define DPTSATKdll DPTSATKDLL +# define DSFLSHdll DSFLSHDLL +# define DSFL1dll DSFL1DLL +# define DSFL2dll DSFL2DLL +# define ENTHALdll ENTHALDLL +# define ENTROdll ENTRODLL +# define ESFLSHdll ESFLSHDLL +# define FGCTYdll FGCTYDLL +# define FPVdll FPVDLL +# define GERG04dll GERG04DLL +# define GETFIJdll GETFIJDLL +# define GETKTVdll GETKTVDLL +# define GIBBSdll GIBBSDLL +# define HSFLSHdll HSFLSHDLL +# define INFOdll INFODLL +# define LIMITKdll LIMITKDLL +# define LIMITSdll LIMITSDLL +# define LIMITXdll LIMITXDLL +# define MELTPdll MELTPDLL +# define MELTTdll MELTTDLL +# define MLTH2Odll MLTH2ODLL +# define NAMEdll NAMEDLL +# define PDFL1dll PDFL1DLL +# define PDFLSHdll PDFLSHDLL +# define PEFLSHdll PEFLSHDLL +# define PHFL1dll PHFL1DLL +# define PHFLSHdll PHFLSHDLL +# define PQFLSHdll PQFLSHDLL +# define PREOSdll PREOSDLL +# define PRESSdll PRESSDLL +# define PSFL1dll PSFL1DLL +# define PSFLSHdll PSFLSHDLL +# define PUREFLDdll PUREFLDDLL +# define QMASSdll QMASSDLL +# define QMOLEdll QMOLEDLL +# define SATDdll SATDDLL +# define SATEdll SATEDLL +# define SATHdll SATHDLL +# define SATPdll SATPDLL +# define SATSdll SATSDLL +# define SATTdll SATTDLL +# define SETAGAdll SETAGADLL +# define SETKTVdll SETKTVDLL +# define SETMIXdll SETMIXDLL +# define SETMODdll SETMODDLL +# define SETREFdll SETREFDLL +# define SETUPdll SETUPDLL +# define SPECGRdll SPECGRDLL +# define SUBLPdll SUBLPDLL +# define SUBLTdll SUBLTDLL +# define SURFTdll SURFTDLL +# define SURTENdll SURTENDLL +# define TDFLSHdll TDFLSHDLL +# define TEFLSHdll TEFLSHDLL +# define THERM0dll THERM0DLL +# define THERM2dll THERM2DLL +# define THERM3dll THERM3DLL +# define THERMdll THERMDLL +# define THFLSHdll THFLSHDLL +# define TPFLSHdll TPFLSHDLL +# define TPFL2dll TPFL2DLL +# define TPRHOdll TPRHODLL +# define TQFLSHdll TQFLSHDLL +# define TRNPRPdll TRNPRPDLL +# define TSFLSHdll TSFLSHDLL +# define VIRBdll VIRBDLL +# define VIRCdll VIRCDLL +# define WMOLdll WMOLDLL +# define XMASSdll XMASSDLL +# define XMOLEdll XMOLEdll +#else +# if !defined(_AIX) && !defined(__hpux) +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +# define SPECGRdll specgrdll_ +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +# endif +# define _fcd char * +# define _cptofcd(a,b) (a) +# define _fcdlen(a) strlen(a) +#endif +#endif + +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +////not a pointer but function type +//typedef void [compiler specific stuff] func_t(int, float); +// +////this is the function declaration +//func_t func; +// +////and this is the pointer type just for convenience +//typedef func_t * func_ptr; + +#ifdef __cplusplus +extern "C" { +#endif + + // pattern to follow: typedef void [compiler specific stuff] func_t(int, float); + + // extra function for setup + typedef void (LIBRARY_API RPVersion_t )( char* ); + typedef void (LIBRARY_API SETPATHdll_t)( const char* ); + // + typedef void (LIBRARY_API ABFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ABFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ACTVYdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API AGdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CCRITdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CP0dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CRITPdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CSATKdll_t)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CV2PKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CVCPKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CVCPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DBFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DDDPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DDDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DHD1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DHFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DIELECdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DOTFILLdll_t)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DPDD2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPTSATKdll_t)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DSFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API ENTHALdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ENTROdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ESFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API FGCTYdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); + typedef void (LIBRARY_API FPVdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API GERG04dll_t)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API GETFIJdll_t)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GETKTVdll_t)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GIBBSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API HSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API INFOdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API LIMITKdll_t)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API LIMITSdll_t)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); + typedef void (LIBRARY_API LIMITXdll_t)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API MELTPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MELTTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MLTH2Odll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API NAMEdll_t)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API PDFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PDFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PQFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PREOSdll_t)(INTEGER &); + typedef void (LIBRARY_API PRESSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API PSFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PUREFLDdll_t)(INTEGER &); + typedef void (LIBRARY_API QMASSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API QMOLEdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATDdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATEdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETAGAdll_t)(INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETKTVdll_t)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMIXdll_t)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMODdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETREFdll_t)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + //typedef void (LIBRARY_API SETUPdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETUPdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*); + typedef void (LIBRARY_API SPECGRdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API SUBLPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SUBLTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURFTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURTENdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TDFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API THERM0dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM3dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERMdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API TPRHOdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TQFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TRNPRPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API VIRBdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API VIRCdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API WMOLdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMASSdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMOLEdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + + + //Declare the functions + RPVersion_t RPVersion; + SETPATHdll_t SETPATHdll; + ABFL1dll_t ABFL1dll; + ABFL2dll_t ABFL2dll; + ACTVYdll_t ACTVYdll; + AGdll_t AGdll; + CCRITdll_t CCRITdll; + CP0dll_t CP0dll; + CRITPdll_t CRITPdll; + CSATKdll_t CSATKdll; + CV2PKdll_t CV2PKdll; + CVCPKdll_t CVCPKdll; + CVCPdll_t CVCPdll; + DBDTdll_t DBDTdll; + DBFL1dll_t DBFL1dll; + DBFL2dll_t DBFL2dll; + DDDPdll_t DDDPdll; + DDDTdll_t DDDTdll; + DEFLSHdll_t DEFLSHdll; + DHD1dll_t DHD1dll; + DHFLSHdll_t DHFLSHdll; + DHFL1dll_t DHFL1dll; + DHFL2dll_t DHFL2dll; + DIELECdll_t DIELECdll; + DOTFILLdll_t DOTFILLdll; + DPDD2dll_t DPDD2dll; + DPDDKdll_t DPDDKdll; + DPDDdll_t DPDDdll; + DPDTKdll_t DPDTKdll; + DPDTdll_t DPDTdll; + DPTSATKdll_t DPTSATKdll; + DSFLSHdll_t DSFLSHdll; + DSFL1dll_t DSFL1dll; + DSFL2dll_t DSFL2dll; + ENTHALdll_t ENTHALdll; + ENTROdll_t ENTROdll; + ESFLSHdll_t ESFLSHdll; + FGCTYdll_t FGCTYdll; + FPVdll_t FPVdll; + GERG04dll_t GERG04dll; + GETFIJdll_t GETFIJdll; + GETKTVdll_t GETKTVdll; + GIBBSdll_t GIBBSdll; + HSFLSHdll_t HSFLSHdll; + INFOdll_t INFOdll; + LIMITKdll_t LIMITKdll; + LIMITSdll_t LIMITSdll; + LIMITXdll_t LIMITXdll; + MELTPdll_t MELTPdll; + MELTTdll_t MELTTdll; + MLTH2Odll_t MLTH2Odll; + NAMEdll_t NAMEdll; + PDFL1dll_t PDFL1dll; + PDFLSHdll_t PDFLSHdll; + PEFLSHdll_t PEFLSHdll; + PHFL1dll_t PHFL1dll; + PHFLSHdll_t PHFLSHdll; + PQFLSHdll_t PQFLSHdll; + PREOSdll_t PREOSdll; + PRESSdll_t PRESSdll; + PSFL1dll_t PSFL1dll; + PSFLSHdll_t PSFLSHdll; + PUREFLDdll_t PUREFLDdll; + QMASSdll_t QMASSdll; + QMOLEdll_t QMOLEdll; + SATDdll_t SATDdll; + SATEdll_t SATEdll; + SATHdll_t SATHdll; + SATPdll_t SATPdll; + SATSdll_t SATSdll; + SATTdll_t SATTdll; + SETAGAdll_t SETAGAdll; + SETKTVdll_t SETKTVdll; + SETMIXdll_t SETMIXdll; + SETMODdll_t SETMODdll; + SETREFdll_t SETREFdll; + SETUPdll_t SETUPdll; + SPECGRdll_t SPECGRdll; + SUBLPdll_t SUBLPdll; + SUBLTdll_t SUBLTdll; + SURFTdll_t SURFTdll; + SURTENdll_t SURTENdll; + TDFLSHdll_t TDFLSHdll; + TEFLSHdll_t TEFLSHdll; + THERM0dll_t THERM0dll; + THERM2dll_t THERM2dll; + THERM3dll_t THERM3dll; + THERMdll_t THERMdll; + THFLSHdll_t THFLSHdll; + TPFLSHdll_t TPFLSHdll; + TPFL2dll_t TPFL2dll; + TPRHOdll_t TPRHOdll; + TQFLSHdll_t TQFLSHdll; + TRNPRPdll_t TRNPRPdll; + TSFLSHdll_t TSFLSHdll; + VIRBdll_t VIRBdll; + VIRCdll_t VIRCdll; + WMOLdll_t WMOLdll; + XMASSdll_t XMASSdll; + XMOLEdll_t XMOLEdll; + + //Define explicit function pointers + typedef RPVersion_t * RPVersion_ptr; + typedef SETPATHdll_t * SETPATHdll_ptr; + typedef ABFL1dll_t * ABFL1dll_ptr; + typedef ABFL2dll_t * ABFL2dll_ptr; + typedef ACTVYdll_t * ACTVYdll_ptr; + typedef AGdll_t * AGdll_ptr; + typedef CCRITdll_t * CCRITdll_ptr; + typedef CP0dll_t * CP0dll_ptr; + typedef CRITPdll_t * CRITPdll_ptr; + typedef CSATKdll_t * CSATKdll_ptr; + typedef CV2PKdll_t * CV2PKdll_ptr; + typedef CVCPKdll_t * CVCPKdll_ptr; + typedef CVCPdll_t * CVCPdll_ptr; + typedef DBDTdll_t * DBDTdll_ptr; + typedef DBFL1dll_t * DBFL1dll_ptr; + typedef DBFL2dll_t * DBFL2dll_ptr; + typedef DDDPdll_t * DDDPdll_ptr; + typedef DDDTdll_t * DDDTdll_ptr; + typedef DEFLSHdll_t * DEFLSHdll_ptr; + typedef DHD1dll_t * DHD1dll_ptr; + typedef DHFLSHdll_t * DHFLSHdll_ptr; + typedef DHFL1dll_t * DHFL1dll_ptr; + typedef DHFL2dll_t * DHFL2dll_ptr; + typedef DIELECdll_t * DIELECdll_ptr; + typedef DOTFILLdll_t * DOTFILLdll_ptr; + typedef DPDD2dll_t * DPDD2dll_ptr; + typedef DPDDKdll_t * DPDDKdll_ptr; + typedef DPDDdll_t * DPDDdll_ptr; + typedef DPDTKdll_t * DPDTKdll_ptr; + typedef DPDTdll_t * DPDTdll_ptr; + typedef DPTSATKdll_t * DPTSATKdll_ptr; + typedef DSFLSHdll_t * DSFLSHdll_ptr; + typedef DSFL1dll_t * DSFL1dll_ptr; + typedef DSFL2dll_t * DSFL2dll_ptr; + typedef ENTHALdll_t * ENTHALdll_ptr; + typedef ENTROdll_t * ENTROdll_ptr; + typedef ESFLSHdll_t * ESFLSHdll_ptr; + typedef FGCTYdll_t * FGCTYdll_ptr; + typedef FPVdll_t * FPVdll_ptr; + typedef GERG04dll_t * GERG04dll_ptr; + typedef GETFIJdll_t * GETFIJdll_ptr; + typedef GETKTVdll_t * GETKTVdll_ptr; + typedef GIBBSdll_t * GIBBSdll_ptr; + typedef HSFLSHdll_t * HSFLSHdll_ptr; + typedef INFOdll_t * INFOdll_ptr; + typedef LIMITKdll_t * LIMITKdll_ptr; + typedef LIMITSdll_t * LIMITSdll_ptr; + typedef LIMITXdll_t * LIMITXdll_ptr; + typedef MELTPdll_t * MELTPdll_ptr; + typedef MELTTdll_t * MELTTdll_ptr; + typedef MLTH2Odll_t * MLTH2Odll_ptr; + typedef NAMEdll_t * NAMEdll_ptr; + typedef PDFL1dll_t * PDFL1dll_ptr; + typedef PDFLSHdll_t * PDFLSHdll_ptr; + typedef PEFLSHdll_t * PEFLSHdll_ptr; + typedef PHFL1dll_t * PHFL1dll_ptr; + typedef PHFLSHdll_t * PHFLSHdll_ptr; + typedef PQFLSHdll_t * PQFLSHdll_ptr; + typedef PREOSdll_t * PREOSdll_ptr; + typedef PRESSdll_t * PRESSdll_ptr; + typedef PSFL1dll_t * PSFL1dll_ptr; + typedef PSFLSHdll_t * PSFLSHdll_ptr; + typedef PUREFLDdll_t * PUREFLDdll_ptr; + typedef QMASSdll_t * QMASSdll_ptr; + typedef QMOLEdll_t * QMOLEdll_ptr; + typedef SATDdll_t * SATDdll_ptr; + typedef SATEdll_t * SATEdll_ptr; + typedef SATHdll_t * SATHdll_ptr; + typedef SATPdll_t * SATPdll_ptr; + typedef SATSdll_t * SATSdll_ptr; + typedef SATTdll_t * SATTdll_ptr; + typedef SETAGAdll_t * SETAGAdll_ptr; + typedef SETKTVdll_t * SETKTVdll_ptr; + typedef SETMIXdll_t * SETMIXdll_ptr; + typedef SETMODdll_t * SETMODdll_ptr; + typedef SETREFdll_t * SETREFdll_ptr; + typedef SETUPdll_t * SETUPdll_ptr; + typedef SPECGRdll_t * SPECGRdll_ptr; + typedef SUBLPdll_t * SUBLPdll_ptr; + typedef SUBLTdll_t * SUBLTdll_ptr; + typedef SURFTdll_t * SURFTdll_ptr; + typedef SURTENdll_t * SURTENdll_ptr; + typedef TDFLSHdll_t * TDFLSHdll_ptr; + typedef TEFLSHdll_t * TEFLSHdll_ptr; + typedef THERM0dll_t * THERM0dll_ptr; + typedef THERM2dll_t * THERM2dll_ptr; + typedef THERM3dll_t * THERM3dll_ptr; + typedef THERMdll_t * THERMdll_ptr; + typedef THFLSHdll_t * THFLSHdll_ptr; + typedef TPFLSHdll_t * TPFLSHdll_ptr; + typedef TPFL2dll_t * TPFL2dll_ptr; + typedef TPRHOdll_t * TPRHOdll_ptr; + typedef TQFLSHdll_t * TQFLSHdll_ptr; + typedef TRNPRPdll_t * TRNPRPdll_ptr; + typedef TSFLSHdll_t * TSFLSHdll_ptr; + typedef VIRBdll_t * VIRBdll_ptr; + typedef VIRCdll_t * VIRCdll_ptr; + typedef WMOLdll_t * WMOLdll_ptr; + typedef XMASSdll_t * XMASSdll_ptr; + typedef XMOLEdll_t * XMOLEdll_ptr; + + + #ifdef __cplusplus + } // extern "C" + #endif + +//#ifdef __cplusplus +//extern "C" { +//#endif +// routines used in henning francke's wrapper +// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, +// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD +// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 +// +////Define explicit function pointers +//fp_RPVersion RPVersion; +//fp_SETPATHdll SETPATHdll; +////Define explicit function pointers +//fp_ABFL1dll ABFL1dll; +//fp_ABFL2dll ABFL2dll; +//fp_ACTVYdll ACTVYdll; +//fp_AGdll AGdll; +//fp_CCRITdll CCRITdll; +//fp_CP0dll CP0dll; +//fp_CRITPdll CRITPdll; +//fp_CSATKdll CSATKdll; +//fp_CV2PKdll CV2PKdll; +//fp_CVCPKdll CVCPKdll; +//fp_CVCPdll CVCPdll; +//fp_DBDTdll DBDTdll; +//fp_DBFL1dll DBFL1dll; +//fp_DBFL2dll DBFL2dll; +//fp_DDDPdll DDDPdll; +//fp_DDDTdll DDDTdll; +//fp_DEFLSHdll DEFLSHdll; +//fp_DHD1dll DHD1dll; +//fp_DHFLSHdll DHFLSHdll; +//fp_DHFL1dll DHFL1dll; +//fp_DHFL2dll DHFL2dll; +//fp_DIELECdll DIELECdll; +//fp_DOTFILLdll DOTFILLdll; +//fp_DPDD2dll DPDD2dll; +//fp_DPDDKdll DPDDKdll; +//fp_DPDDdll DPDDdll; +//fp_DPDTKdll DPDTKdll; +//fp_DPDTdll DPDTdll; +//fp_DPTSATKdll DPTSATKdll; +//fp_DSFLSHdll DSFLSHdll; +//fp_DSFL1dll DSFL1dll; +//fp_DSFL2dll DSFL2dll; +//fp_ENTHALdll ENTHALdll; +//fp_ENTROdll ENTROdll; +//fp_ESFLSHdll ESFLSHdll; +//fp_FGCTYdll FGCTYdll; +//fp_FPVdll FPVdll; +//fp_GERG04dll GERG04dll; +//fp_GETFIJdll GETFIJdll; +//fp_GETKTVdll GETKTVdll; +//fp_GIBBSdll GIBBSdll; +//fp_HSFLSHdll HSFLSHdll; +//fp_INFOdll INFOdll; +//fp_LIMITKdll LIMITKdll; +//fp_LIMITSdll LIMITSdll; +//fp_LIMITXdll LIMITXdll; +//fp_MELTPdll MELTPdll; +//fp_MELTTdll MELTTdll; +//fp_MLTH2Odll MLTH2Odll; +//fp_NAMEdll NAMEdll; +//fp_PDFL1dll PDFL1dll; +//fp_PDFLSHdll PDFLSHdll; +//fp_PEFLSHdll PEFLSHdll; +//fp_PHFL1dll PHFL1dll; +//fp_PHFLSHdll PHFLSHdll; +//fp_PQFLSHdll PQFLSHdll; +//fp_PREOSdll PREOSdll; +//fp_PRESSdll PRESSdll; +//fp_PSFL1dll PSFL1dll; +//fp_PSFLSHdll PSFLSHdll; +//fp_PUREFLDdll PUREFLDdll; +//fp_QMASSdll QMASSdll; +//fp_QMOLEdll QMOLEdll; +//fp_SATDdll SATDdll; +//fp_SATEdll SATEdll; +//fp_SATHdll SATHdll; +//fp_SATPdll SATPdll; +//fp_SATSdll SATSdll; +//fp_SATTdll SATTdll; +//fp_SETAGAdll SETAGAdll; +//fp_SETKTVdll SETKTVdll; +//fp_SETMIXdll SETMIXdll; +//fp_SETMODdll SETMODdll; +//fp_SETREFdll SETREFdll; +//fp_SETUPdll SETUPdll; +//fp_SPECGRdll SPECGRdll; +//fp_SUBLPdll SUBLPdll; +//fp_SUBLTdll SUBLTdll; +//fp_SURFTdll SURFTdll; +//fp_SURTENdll SURTENdll; +//fp_TDFLSHdll TDFLSHdll; +//fp_TEFLSHdll TEFLSHdll; +//fp_THERM0dll THERM0dll; +//fp_THERM2dll THERM2dll; +//fp_THERM3dll THERM3dll; +//fp_THERMdll THERMdll; +//fp_THFLSHdll THFLSHdll; +//fp_TPFLSHdll TPFLSHdll; +//fp_TPFL2dll TPFL2dll; +//fp_TPRHOdll TPRHOdll; +//fp_TQFLSHdll TQFLSHdll; +//fp_TRNPRPdll TRNPRPdll; +//fp_TSFLSHdll TSFLSHdll; +//fp_VIRBdll VIRBdll; +//fp_VIRCdll VIRCdll; +//fp_WMOLdll WMOLdll; +//fp_XMASSdll XMASSdll; +//fp_XMOLEdll XMOLEdll; + +//#ifdef __cplusplus +//} // extern "C" +//#endif + + +//#ifdef __cplusplus +//extern "C" { +//#endif +// // extra function for setup +// void RPVersion ( char* ); +// void SETPATHdll( const char* ); +// // +// void ABFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void ABFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void ACTVYdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void AGdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void CCRITdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void CP0dll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void CRITPdll(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void CSATKdll(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void CV2PKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void CVCPKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void CVCPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void DBDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DBFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DBFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DDDPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DDDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DHD1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void DHFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke +// void DHFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke +// void DHFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DIELECdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DOTFILLdll(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DPDD2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DPDDKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void DPDDdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DPDTKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void DPDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void DPTSATKdll(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void DSFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke +// void DSFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke +// void ENTHALdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void ENTROdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void ESFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void FGCTYdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); +// void FPVdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void GERG04dll(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); +// void GETFIJdll(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); +// void GETKTVdll(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); +// void GIBBSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void HSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void INFOdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void LIMITKdll(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); +// void LIMITSdll(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); +// void LIMITXdll(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); +// void MELTPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void MELTTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void MLTH2Odll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void NAMEdll(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); +// void PDFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PDFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PHFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PHFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PQFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PREOSdll(INTEGER &); +// void PRESSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void PSFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void PUREFLDdll(INTEGER &); +// void QMASSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void QMOLEdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SATDdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); +// void SATEdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SATHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SATPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); +// void SATSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SATTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); +// void SETAGAdll(INTEGER &,char*,INTEGER ); +// void SETKTVdll(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); +// void SETMIXdll(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); +// void SETMODdll(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); +// void SETREFdll(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); +// //void SETUPdll(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); +// void SETUPdll(INTEGER &,char*,char*,char*,INTEGER &,char*); +// void SPECGRdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void SUBLPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SUBLTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SURFTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void SURTENdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TDFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void THERM0dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void THERM2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void THERM3dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void THERMdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); +// void THFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TPFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TPFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke +// void TPRHOdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TQFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TRNPRPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void TSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); +// void VIRBdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void VIRCdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void WMOLdll(DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void XMASSdll(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +// void XMOLEdll(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); +//#ifdef __cplusplus +//} // extern "C" +//#endif +// REFPROP_H +#endif +// routines used in henning francke's wrapper +// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, +// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD +// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 +// From b2ef510ef50d41cb293b3ce86cfca3e4879b2161 Mon Sep 17 00:00:00 2001 From: jowr Date: Mon, 1 Oct 2012 15:58:41 -0700 Subject: [PATCH 07/57] 2012:10:02 00:53 - Updated the readme, started on a wrapper with the POCO framework. Now complete change yet because the Poco version is approximately 2.5 times slower. added a bash script to create function listings, just for convenience during development. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 7 +- _REFPROP-Wrapper/Version 0.5_linux/list.bsh | 17 + .../Version 0.5_linux/refprop_wrapper.cpp | 50 +- .../refprop_wrapper.poco.cpp | 954 +++++++++++ .../Version 0.5_linux/src/refprop-ftn.cpp | 191 ++- .../Version 0.5_linux/src/refprop_lib.h | 1498 ++++++++--------- readme.txt => readme.md | 45 +- 7 files changed, 1942 insertions(+), 820 deletions(-) create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/list.bsh create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp rename readme.txt => readme.md (60%) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index c90d5d6..5bb6255 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -155,7 +155,12 @@ $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION): $(THEWRAPPER)$(HEADEREXTENSION) .PHONY : wrapper wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader library - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) -lPocoFoundation + +#.PHONY : wrapper +#wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) +#$(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader library +# ar -cvq $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) $(THEWRAPPER).o .PHONY : test test : $(THETEST) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/list.bsh b/_REFPROP-Wrapper/Version 0.5_linux/list.bsh new file mode 100644 index 0000000..b334bc6 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/list.bsh @@ -0,0 +1,17 @@ +#!/bin/bash +# +function defineFunction { + echo "$1_TYPE * $1 = ($1_TYPE *) library.getSymbol($1_NAME);" +} +# +## declare an array variable +# declare -a arr=(RPVersion SETPATHdll ABFL1dll ABFL2dll ACTVYdll AGdll CCRITdll CP0dll CRITPdll CSATKdll CV2PKdll CVCPKdll CVCPdll DBDTdll DBFL1dll DBFL2dll DDDPdll DDDTdll DEFLSHdll DHD1dll DHFLSHdll DHFL1dll DHFL2dll DIELECdll DOTFILLdll DPDD2dll DPDDKdll DPDDdll DPDTKdll DPDTdll DPTSATKdll DSFLSHdll DSFL1dll DSFL2dll ENTHALdll ENTROdll ESFLSHdll FGCTYdll FPVdll GERG04dll GETFIJdll GETKTVdll GIBBSdll HSFLSHdll INFOdll LIMITKdll LIMITSdll LIMITXdll MELTPdll MELTTdll MLTH2Odll NAMEdll PDFL1dll PDFLSHdll PEFLSHdll PHFL1dll PHFLSHdll PQFLSHdll PREOSdll PRESSdll PSFL1dll PSFLSHdll PUREFLDdll QMASSdll QMOLEdll SATDdll SATEdll SATHdll SATPdll SATSdll SATTdll SETAGAdll SETKTVdll SETMIXdll SETMODdll SETREFdll SETUPdll SPECGRdll SUBLPdll SUBLTdll SURFTdll SURTENdll TDFLSHdll TEFLSHdll THERM0dll THERM2dll THERM3dll THERMdll THFLSHdll TPFLSHdll TPFL2dll TPRHOdll TQFLSHdll TRNPRPdll TSFLSHdll VIRBdll VIRCdll WMOLdll XMASSdll XMOLEdll) +# These ones are used in the wrapper +declare -a arr=(WMOLdll TPFL2dll TPFLSHdll PHFL1dll PHFLSHdll PDFL1dll PDFLSHdll PSFLSHdll PQFLSHdll THFLSHdll TDFLSHdll TSFLSHdll TQFLSHdll DHFL1dll DHFL2dll DHFLSHdll HSFLSHdll DSFL1dll DSFL2dll DSFLSHdll TRNPRPdll SATTdll SATPdll SATDdll) +# +## now loop through the above array +for i in ${arr[@]} +do + defineFunction $i # or do whatever with individual element of the array +done + diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp index 74c03ed..94d5262 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp @@ -1,6 +1,6 @@ /* - wrapper code for a static library containing functions from the dynamic library refprop.dll - to be used from Modelica + wrapper code for a static library containing functions from the dynamic + library librefprop.so to be used from Modelica This file is released under the Modelica License 2. @@ -12,32 +12,56 @@ GFZ German Research Centre for Geosciences Telegrafenberg, D-14473 Potsdam - Modified for portability to Linux and - introduction of POCO library in 2012 by + Modified for Linux in 2012 by Jorrit Wronski (jowr@mek.dtu.dk) DTU Mechanical Engineering needs - librefprop.h - header for librefprop.so, based on examples - refprop_wrapper.h - header for static REFPROP_wrapper.a, also needed by Dymola + refprop.h - header for librefprop.so, based on examples + refprop_wrapper.h - header for REFPROP_wrapper.so, also needed by Dymola Use the provided makefile to install the library file from source. */ //#define DEBUGMODE 1 +// +//#include "Poco/SharedLibrary.h" +//using Poco::SharedLibrary; +// +//typedef void (*HelloFunc)(); // function pointer type +// +// +// +// +//typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double &); +// +////Define explicit function pointers +//fp_ABFL1dllTYPE ABFL1dll; +// +// +//int main(int argc, char** argv) +//{ +//std::string path("TestLibrary"); +//path.append(SharedLibrary::suffix()); // adds ".dll" or ".so" +//SharedLibrary library(path); // will also load the library +//HelloFunc func = (HelloFunc) library.getSymbol("hello"); +//func(); +//library.unload(); +//} +//return 0; + + #include #if defined(WIN32) || defined(_WIN32) # include -# include "REFPROP_dll.h" #else // assuming Linux system # include # include -# include -//# include // dlopen etc # include // tolower etc #endif //# error "Could not determine system." +#include #include "refprop_wrapper.h" @@ -48,6 +72,7 @@ const long lengthofreference=3; const long refpropcharlength=255; const long ncmax=20; // Note: ncmax is the max number of components +//static const char RP_ static char const GB_optId = '-' ; // - under UNIX static char const GB_altOptId = '+' ; // + under UNIX static char const GB_asciiEsc = '\\' ; // under UNIX @@ -121,6 +146,13 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, voi strcat(FLD_PATH, GB_preferredPathSep); } + //std::string path("TestLibrary"); + //path.append(SharedLibrary::suffix()); // adds ".dll" or ".so" + //SharedLibrary library(path); // will also load the library + //HelloFunc func = (HelloFunc) library.getSymbol("hello"); + //func(); + //library.unload(); + //*RefpropdllInstance = LoadLibrary(DLL_PATH); // RefpropdllInstance = dlopen(DLL_PATH, RTLD_LAZY); // if (!RefpropdllInstance){ diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp new file mode 100644 index 0000000..548d4e5 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp @@ -0,0 +1,954 @@ +/* + wrapper code for a static library containing functions from the dynamic library refprop.dll + to be used from Modelica + + This file is released under the Modelica License 2. + + Coded in 2010 by + Henning Francke + francke@gfz-potsdam.de + + Helmholtz Centre Potsdam + GFZ German Research Centre for Geosciences + Telegrafenberg, D-14473 Potsdam + + Modified for portability to Linux and + introduction of POCO library in 2012 by + Jorrit Wronski (jowr@mek.dtu.dk) + DTU Mechanical Engineering + + needs + librefprop.h - header for librefprop.so, based on examples + refprop_wrapper.h - header for static REFPROP_wrapper.a, also needed by Dymola + + Use the provided makefile to install the library file from source. +*/ + +//#define DEBUGMODE 1 + +#include +#if defined(WIN32) || defined(_WIN32) +# include +# include "REFPROP_dll.h" +#else // assuming Linux system +# include +# include +# include +//# include // dlopen etc +# include // tolower etc +#endif +//# error "Could not determine system." +#include "refprop_wrapper.h" + +// get the POCO classes +#include "Poco/SharedLibrary.h" +#include "Poco/Path.h" +#include "Poco/File.h" +#include "Poco/Environment.h" +#include "Poco/String.h" + +// Some constants... +const long filepathlength=1024; +const long errormessagelength=255+filepathlength; +const long lengthofreference=3; +const long refpropcharlength=255; +const long ncmax=20; // Note: ncmax is the max number of components + +//Poco::SharedLibrary RefpropdllInstance; +char loadedfluids[refpropcharlength]; + +//// Define the functions either by their pointers or type. +//WMOLdll_POINTER WMOLdll; +//TPFL2dll_POINTER TPFL2dll; +//TPFLSHdll_POINTER TPFLSHdll; +//PHFL1dll_POINTER PHFL1dll; +//PHFLSHdll_POINTER PHFLSHdll; +//PDFL1dll_POINTER PDFL1dll; +//PDFLSHdll_POINTER PDFLSHdll; +//PSFLSHdll_POINTER PSFLSHdll; +//PQFLSHdll_POINTER PQFLSHdll; +//THFLSHdll_POINTER THFLSHdll; +//TDFLSHdll_POINTER TDFLSHdll; +//TSFLSHdll_POINTER TSFLSHdll; +//TQFLSHdll_POINTER TQFLSHdll; +//DHFL1dll_POINTER DHFL1dll; +//DHFL2dll_POINTER DHFL2dll; +//DHFLSHdll_POINTER DHFLSHdll; +//HSFLSHdll_POINTER HSFLSHdll; +//DSFL1dll_POINTER DSFL1dll; +//DSFL2dll_POINTER DSFL2dll; +//DSFLSHdll_POINTER DSFLSHdll; +//TRNPRPdll_POINTER TRNPRPdll; +//SATTdll_POINTER SATTdll; +//SATPdll_POINTER SATPdll; +//SATDdll_POINTER SATDdll; + + +char *str_replace(char *str, char *search, char *replace, long *count) { + int i,n_ret; + int newlen = strlen(replace); + int oldlen = strlen(search); + char *ret; + *count = 0; + + //count occurrences of searchstring + for (i = 0; oldlen && str[i]; ++i) + if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr + ++*count, i+=oldlen - 1; + } + ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); + if (!ret){ + printf("Could not allocate memory"); + return ""; + } + + if (!*count){ + strncpy(ret,str,n_ret); + //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); + }else{ + i = 0; + while (*str) + if (strstr(str, search) == str) + strncpy(&ret[i], replace,n_ret-i-1), + i += newlen, + str += oldlen; + else + ret[i++] = *str++; + ret[i] = '\0'; + } + return ret; +} + +int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, char* errormsg, int DEBUGMODE){ +// Sets up the interface to the REFPROP.DLL +// is called by props_REFPROP and satprops_REFPROP +// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; + + long ierr=0; + + if (strlen(REFPROP_PATH)>filepathlength){ + sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); + return 0; + } + + char* REFPROP_PATH_CHAR = REFPROP_PATH; + char* FLUIDS_CHAR = "fluids"; + char* LIBRARY_CHAR; + + + Poco::Path REF_PATH(true),FLD_PATH(true),LIB_PATH(true); // all paths will be absolute + + REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); + if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); + Poco::File theFile(REF_PATH); + if ( !theFile.isDirectory() || !theFile.canRead() ){ + sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + return 0; + } + + FLD_PATH.parse(REF_PATH.toString()); + FLD_PATH.pushDirectory(FLUIDS_CHAR); + + LIB_PATH.parse(REF_PATH.toString()); + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + LIBRARY_CHAR = "librefprop.so"; + } else { + LIBRARY_CHAR = "refprop.dll"; + } + LIB_PATH.setFileName(LIBRARY_CHAR); + + if (DEBUGMODE) printf ("Comparison of fluids : %i \n", strcmp(fluidnames,loadedfluids) ); +// if (DEBUGMODE) printf ("Comparison of library: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); +// if (strcmp(fluidnames,loadedfluids)==0) { +//// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())==0 ) { +//// sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); +// if (DEBUGMODE) printf ("Returning: %s and %s \n", RefpropdllInstance.getPath().c_str(),fluidnames ); +// return 0; +//// } +// } + + if (DEBUGMODE) { + printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); + printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); + printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); + printf ("Running on: %s \n", Poco::Environment::osName().c_str()); + } + + theFile = Poco::File(LIB_PATH); + if ( !theFile.isFile() || !theFile.canExecute() ){ + sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); + return 0; + } + char LIB_PATH_CHAR[filepathlength]; + strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); + + theFile = Poco::File(FLD_PATH); + if ( !theFile.isDirectory() || !theFile.canRead() ){ + sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + return 0; + } + char FLD_PATH_CHAR[filepathlength]; + strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + +//// First we load the library with the POCO foundation +//// classes and then define all the needed functions +//// by their names and a cast to the correct type. +// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); +// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); +// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); +// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { +// RefpropdllInstance.unload(); +// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); +// RefpropdllInstance.load(LIB_PATH_CHAR); +// } +// +// if (!RefpropdllInstance.isLoaded()){ +// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); +// return 100; +// } + + + char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; + char *hf; + + strcpy(loadedfluids,fluidnames); + //parse fluid composition string and insert absolute paths + char replace[filepathlength+6]; + strcpy(replace,".FLD|"); + //if (DEBUGMODE) printf("REPLACE: %s\n",replace); + strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); + + int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; + hf = (char*) calloc(hf_len, sizeof(char)); + + strncpy(hf,FLD_PATH_CHAR,hf_len); + strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... + if (++*nX>ncmax){ //...that's why nX is incremented + sprintf(errormsg,"Too many components (More than %i)\n",ncmax); + return 0; + } + strncat(hf,".FLD",hf_len-strlen(hf)); + if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); + + strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path + strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); + strcpy(hrf,"DEF"); + + +// SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); + if (DEBUGMODE) printf("Running SETUPdll...\n"); + SETUPdll(*nX, hf, hfmix, hrf, ierr, herr); + if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); + +// WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); +// TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); +// TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); +// PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); +// PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); +// PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); +// PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); +// PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); +// PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); +// THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); +// TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); +// TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); +// TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); +// DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); +// DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); +// DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); +// HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); +// DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); +// DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); +// DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); +// TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); +// SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); +// SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); +// SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); + + +// if (DEBUGMODE) printf("Error code processing...\n"); + switch(ierr){ + case 101: + //strcpy(errormsg,"error in opening file"); +// if (DEBUGMODE) printf("Error 101\n"); + sprintf(errormsg,"error in opening file %s",hf); + break; + case 102: +// if (DEBUGMODE) printf("Error 102\n"); + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: +// if (DEBUGMODE) printf("Error -103\n"); + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: +// if (DEBUGMODE) printf("Error 104\n"); + strcpy(errormsg,"error in setup of model"); + break; + case 105: +// if (DEBUGMODE) printf("Error 105\n"); + strcpy(errormsg,"specified model not found"); + break; + case 111: +// if (DEBUGMODE) printf("Error 111\n"); + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: +// if (DEBUGMODE) printf("Error 112\n"); + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: +// if (DEBUGMODE) printf("Error 114\n"); + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 0: + break; + default: +// if (DEBUGMODE) printf("Unknown error\n"); + strcpy(errormsg,"Unknown error"); + //strcpy(errormsg,"Setup was successful!"); + strncpy(errormsg,herr,errormessagelength); + break; + } + free(hf); + return ierr; +} + + +double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevars: string of any combination of two variables out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevar1,statevar2: values of the two variables specified in statevars + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values (props[0] containing error number) + errormsg: string containing error message +*/ + char statevars[3]; + double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; + long nX,ierr=0; //zero means no error + char herr[errormessagelength+1]; +// HINSTANCE RefpropdllInstance;// Then have windows load the library. +// Poco::SharedLibrary RefpropdllInstance(""); + + if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); + + //initialize interface to REFPROP.dll +// if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ +// printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); +// return 0; +// } + if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ + printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); + return 0; + } + + //CALCULATE MOLAR MASS +// WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); +// WMOLdll_TYPE * WMOLdll = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); + WMOLdll(x,wm); +// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); + wm /= 1000; //g/mol -> kg/mol + + //identify and assign passed state variables + statevars[0] = tolower(statevars_in[0]); + statevars[1] = tolower(statevars_in[1]); + statevars[2] = '\0'; + if (statevars[0]!='\0'){ + if (statevars[0]==statevars[1]){ + props[0] = 3; + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); + return 0; + } + for (int ii=0;ii<2;ii++){ + val = (ii==0?statevar1:statevar2); + switch(statevars[ii]){ + case 'p': + p = val/1000; //Pa->kPa + break; + case 't': + T = val; + break; + case 's': + s = val*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = val*wm; //J/kg --> kJ/mol + break; + case 'd': + d = val/wm/1000; //kg/m� -> mol/dm� + break; + case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + q = val; + break; + default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ + return 0; + } + } + } + +/* +//...If phase j is known, call TPRHOdll: + long j=2; //phase definition(j=1: Liquid, j=2: Vapor) + long tmp_int=0; + TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); + TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); +*/ +//...If phase is not known, call TPFLSH + double xliq[ncmax],xvap[ncmax],f[ncmax]; + long kq=2;/* additional input--only for TQFLSH and PQFLSH + kq--flag specifying units for input quality + kq = 1 quality on MOLAR basis [moles vapor/total moles] + kq = 2 quality on MASS basis [mass vapor/total mass]*/ +// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); + if (ierr==0){ + if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ +// strcat(errormsg,"Bin in TP!"); + if (phase==2){ //fluid state is known to be two phase +// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); + TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + }else{ +// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); + TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ +/* if (phase==1){ //fluid state is known to be single phase + PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); + PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ +// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ + if (phase==1){ //fluid state is known to be single phase +// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); + PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); + }else{ +// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); + PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); + PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ +// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); + PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ +// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); + PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); +// strcat(errormsg,"Bin in PQ!"); + }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); + THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); + }else{*/ +// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ +// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ +// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); + long kr = 2; + TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ +// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); + TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); + DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); + DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); + DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + break; + } + }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ +// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); + HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); + DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); + DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); + DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + break; + } + }else + sprintf(errormsg,"Unknown combination of state variables! %s", statevars); + } + + switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE + case 'v': //dynamic viscosity uPa.s + case 'l': //thermal conductivity W/m.K +// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); + TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); + break; + } + + + switch(ierr){ + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 4: + sprintf(errormsg,"P=%f < 0",p); + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",T,p); + break; + case 8: + strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); + break; + case 9: + sprintf(errormsg,"x or T=%f out of range",T); + break; + case 12: + sprintf(errormsg,"x out of range and P=%f < 0",p); + break; + case 13: + sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",d); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",d); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); + break; + default: + strncpy(errormsg,herr,errormessagelength); + break; + } + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOLdll(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOLdll(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� + e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) + cv /= wm; + cp /= wm; + p *= 1000; //kPa->Pa + if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis + eta/=1e6; //uPa.s -> Pa.s + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = e; //inner energy + props[9] = h; //specific enthalpy + props[10] = s;//specific entropy + props[11] = cv; + props[12] = cp; + props[13] = w; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;ii kg/mol + + if (DEBUGMODE) printf("\nwm converted.\n"); + + if (DEBUGMODE) printf("\statevar is %s \n",statevar_in); + //identify and assign passed state variables + // char tmpstr[1]; + // strcpy(tmpstr,statevar[0]); + // statevar = toLowerCase(tmpstr); + //statevar[0] = tolower(statevar[0]); + char statevar[1]; + statevar[0] = tolower(statevar_in[0]); + if (DEBUGMODE) printf("\nstatevar lowercase.\n"); + if (statevar[0]!='\0'){ +// if (strcmp(statevar[0],"")){ +// if (statevar[0] != NULL){ + if (DEBUGMODE) printf("\nentering statevar switch.\n"); + switch(statevar[0]){ + case 'p': + p = statevarval/1000; //Pa->kPa + break; + case 't': + T = statevarval; + break; + case 'd': + d = statevarval/wm/1000; //kg/m� -> mol/dm� + break; +/* case 's': + s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = statevarval*wm; //J/kg --> kJ/mol + break; +*/ default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable: %c", statevarval); + return 0; + } + } + + if (DEBUGMODE) printf("\nstatevar checked.\n"); + + double xliq[ncmax],xvap[ncmax],f[ncmax]; + + long j=2,kr; +/* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) +*/ + if (ierr==0) + if (~strcmp(statevar,"t")){ +// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); + SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + }else if (~strcmp(statevar,"p")){ +// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); + SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + }else if (~strcmp(statevar,"d")){ +// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); + SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } + + switch(ierr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 8: + strcpy(errormsg,"x out of range"); + break; + case 9: + strcpy(errormsg,"T and x out of range"); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + strncpy(errormsg,herr,errormessagelength); + break; + } + + /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); + SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); + SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOLdll(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOLdll(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� +/* e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) +*/ p *= 1000; //kPa->Pa + } + + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in kPa->Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = 0; + props[8] = 0; //inner energy + props[9] = 0; //specific enthalpy + props[10] = 0;//specific entropy + props[11] = 0; + props[12] = 0; + props[13] = 0; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;ii -# define RPVersion RPVERSION -# define SETPATHdll SETPATHDLL -# define ABFL1dll ABFL1DLL -# define ABFL2dll ABFL2DLL -# define ACTVYdll ACTVYDLL -# define AGdll AGDLL -# define CCRITdll CCRITDLL -# define CP0dll CP0DLL -# define CRITPdll CRITPDLL -# define CSATKdll CSATKDLL -# define CV2PKdll CV2PKDLL -# define CVCPKdll CVCPKDLL -# define CVCPdll CVCPDLL -# define DBDTdll DBDTDLL -# define DBFL1dll DBFL1DLL -# define DBFL2dll DBFL2DLL -# define DDDPdll DDDPDLL -# define DDDTdll DDDTDLL -# define DEFLSHdll DEFLSHDLL -# define DHD1dll DHD1DLL -# define DHFL1dll DHFL1DLL -# define DHFL2dll DHFL2DLL -# define DHFLSHdll DHFLSHDLL -# define DIELECdll DIELECDLL -# define DOTFILLdll DOTFILLDLL -# define DPDD2dll DPDD2DLL -# define DPDDKdll DPDDKDLL -# define DPDDdll DPDDDLL -# define DPDTKdll DPDTKDLL -# define DPDTdll DPDTDLL -# define DPTSATKdll DPTSATKDLL -# define DSFLSHdll DSFLSHDLL -# define DSFL1dll DSFL1DLL -# define DSFL2dll DSFL2DLL -# define ENTHALdll ENTHALDLL -# define ENTROdll ENTRODLL -# define ESFLSHdll ESFLSHDLL -# define FGCTYdll FGCTYDLL -# define FPVdll FPVDLL -# define GERG04dll GERG04DLL -# define GETFIJdll GETFIJDLL -# define GETKTVdll GETKTVDLL -# define GIBBSdll GIBBSDLL -# define HSFLSHdll HSFLSHDLL -# define INFOdll INFODLL -# define LIMITKdll LIMITKDLL -# define LIMITSdll LIMITSDLL -# define LIMITXdll LIMITXDLL -# define MELTPdll MELTPDLL -# define MELTTdll MELTTDLL -# define MLTH2Odll MLTH2ODLL -# define NAMEdll NAMEDLL -# define PDFL1dll PDFL1DLL -# define PDFLSHdll PDFLSHDLL -# define PEFLSHdll PEFLSHDLL -# define PHFL1dll PHFL1DLL -# define PHFLSHdll PHFLSHDLL -# define PQFLSHdll PQFLSHDLL -# define PREOSdll PREOSDLL -# define PRESSdll PRESSDLL -# define PSFL1dll PSFL1DLL -# define PSFLSHdll PSFLSHDLL -# define PUREFLDdll PUREFLDDLL -# define QMASSdll QMASSDLL -# define QMOLEdll QMOLEDLL -# define SATDdll SATDDLL -# define SATEdll SATEDLL -# define SATHdll SATHDLL -# define SATPdll SATPDLL -# define SATSdll SATSDLL -# define SATTdll SATTDLL -# define SETAGAdll SETAGADLL -# define SETKTVdll SETKTVDLL -# define SETMIXdll SETMIXDLL -# define SETMODdll SETMODDLL -# define SETREFdll SETREFDLL -# define SETUPdll SETUPDLL -# define SPECGRdll SPECGRDLL -# define SUBLPdll SUBLPDLL -# define SUBLTdll SUBLTDLL -# define SURFTdll SURFTDLL -# define SURTENdll SURTENDLL -# define TDFLSHdll TDFLSHDLL -# define TEFLSHdll TEFLSHDLL -# define THERM0dll THERM0DLL -# define THERM2dll THERM2DLL -# define THERM3dll THERM3DLL -# define THERMdll THERMDLL -# define THFLSHdll THFLSHDLL -# define TPFLSHdll TPFLSHDLL -# define TPFL2dll TPFL2DLL -# define TPRHOdll TPRHODLL -# define TQFLSHdll TQFLSHDLL -# define TRNPRPdll TRNPRPDLL -# define TSFLSHdll TSFLSHDLL -# define VIRBdll VIRBDLL -# define VIRCdll VIRCDLL -# define WMOLdll WMOLDLL -# define XMASSdll XMASSDLL +// Define compiler specific calling conventions +// for the shared library. +# define LIBRARY_API __stdcall // __declspec(dllexport) +// Do not define function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +# define SPECGRdll SPECGRdll +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll # define XMOLEdll XMOLEdll -#else -# if !defined(_AIX) && !defined(__hpux) -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -# define SPECGRdll specgrdll_ -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -# endif -# define _fcd char * -# define _cptofcd(a,b) (a) -# define _fcdlen(a) strlen(a) -#endif -#endif +#else // defined(WIN32) || defined(_WIN32) +// Define compiler specific calling conventions +// for the shared library. +# define LIBRARY_API +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +# ifdef _CRAY +# include +# define RPVersion RPVERSION +# define SETPATHdll SETPATHDLL +# define ABFL1dll ABFL1DLL +# define ABFL2dll ABFL2DLL +# define ACTVYdll ACTVYDLL +# define AGdll AGDLL +# define CCRITdll CCRITDLL +# define CP0dll CP0DLL +# define CRITPdll CRITPDLL +# define CSATKdll CSATKDLL +# define CV2PKdll CV2PKDLL +# define CVCPKdll CVCPKDLL +# define CVCPdll CVCPDLL +# define DBDTdll DBDTDLL +# define DBFL1dll DBFL1DLL +# define DBFL2dll DBFL2DLL +# define DDDPdll DDDPDLL +# define DDDTdll DDDTDLL +# define DEFLSHdll DEFLSHDLL +# define DHD1dll DHD1DLL +# define DHFL1dll DHFL1DLL +# define DHFL2dll DHFL2DLL +# define DHFLSHdll DHFLSHDLL +# define DIELECdll DIELECDLL +# define DOTFILLdll DOTFILLDLL +# define DPDD2dll DPDD2DLL +# define DPDDKdll DPDDKDLL +# define DPDDdll DPDDDLL +# define DPDTKdll DPDTKDLL +# define DPDTdll DPDTDLL +# define DPTSATKdll DPTSATKDLL +# define DSFLSHdll DSFLSHDLL +# define DSFL1dll DSFL1DLL +# define DSFL2dll DSFL2DLL +# define ENTHALdll ENTHALDLL +# define ENTROdll ENTRODLL +# define ESFLSHdll ESFLSHDLL +# define FGCTYdll FGCTYDLL +# define FPVdll FPVDLL +# define GERG04dll GERG04DLL +# define GETFIJdll GETFIJDLL +# define GETKTVdll GETKTVDLL +# define GIBBSdll GIBBSDLL +# define HSFLSHdll HSFLSHDLL +# define INFOdll INFODLL +# define LIMITKdll LIMITKDLL +# define LIMITSdll LIMITSDLL +# define LIMITXdll LIMITXDLL +# define MELTPdll MELTPDLL +# define MELTTdll MELTTDLL +# define MLTH2Odll MLTH2ODLL +# define NAMEdll NAMEDLL +# define PDFL1dll PDFL1DLL +# define PDFLSHdll PDFLSHDLL +# define PEFLSHdll PEFLSHDLL +# define PHFL1dll PHFL1DLL +# define PHFLSHdll PHFLSHDLL +# define PQFLSHdll PQFLSHDLL +# define PREOSdll PREOSDLL +# define PRESSdll PRESSDLL +# define PSFL1dll PSFL1DLL +# define PSFLSHdll PSFLSHDLL +# define PUREFLDdll PUREFLDDLL +# define QMASSdll QMASSDLL +# define QMOLEdll QMOLEDLL +# define SATDdll SATDDLL +# define SATEdll SATEDLL +# define SATHdll SATHDLL +# define SATPdll SATPDLL +# define SATSdll SATSDLL +# define SATTdll SATTDLL +# define SETAGAdll SETAGADLL +# define SETKTVdll SETKTVDLL +# define SETMIXdll SETMIXDLL +# define SETMODdll SETMODDLL +# define SETREFdll SETREFDLL +# define SETUPdll SETUPDLL +# define SPECGRdll SPECGRDLL +# define SUBLPdll SUBLPDLL +# define SUBLTdll SUBLTDLL +# define SURFTdll SURFTDLL +# define SURTENdll SURTENDLL +# define TDFLSHdll TDFLSHDLL +# define TEFLSHdll TEFLSHDLL +# define THERM0dll THERM0DLL +# define THERM2dll THERM2DLL +# define THERM3dll THERM3DLL +# define THERMdll THERMDLL +# define THFLSHdll THFLSHDLL +# define TPFLSHdll TPFLSHDLL +# define TPFL2dll TPFL2DLL +# define TPRHOdll TPRHODLL +# define TQFLSHdll TQFLSHDLL +# define TRNPRPdll TRNPRPDLL +# define TSFLSHdll TSFLSHDLL +# define VIRBdll VIRBDLL +# define VIRCdll VIRCDLL +# define WMOLdll WMOLDLL +# define XMASSdll XMASSDLL +# define XMOLEdll XMOLEDLL +# else // _CRAY not defined +# if !defined(_AIX) && !defined(__hpux) +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +# define SPECGRdll specgrdll_ +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +# endif // !defined(_AIX) && !defined(__hpux) +# endif // _CRAY not defined, else branch +#endif // defined(WIN32) || defined(_WIN32), else branch + + +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +//#define TEST_FUNC test_func +//#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) + +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) + // I'll try to follow this example from: // http://www.gershnik.com/tips/cpp.asp @@ -244,552 +463,317 @@ typedef int LOGICAL; #ifdef __cplusplus extern "C" { #endif + // extra function for setup + typedef void (LIBRARY_API RPVersion_TYPE )( char* ); + typedef void (LIBRARY_API SETPATHdll_TYPE)( const char* ); + // + typedef void (LIBRARY_API ABFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ABFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ACTVYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API AGdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CCRITdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CP0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CRITPdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CV2PKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CVCPKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CVCPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DBFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DDDPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DDDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DHD1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DIELECdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DOTFILLdll_TYPE)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DPDD2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPTSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DSFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API ENTHALdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ENTROdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ESFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API FGCTYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); + typedef void (LIBRARY_API FPVdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API GERG04dll_TYPE)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API GETFIJdll_TYPE)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GIBBSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API HSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API INFOdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API LIMITKdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API LIMITSdll_TYPE)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); + typedef void (LIBRARY_API LIMITXdll_TYPE)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API MELTPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MELTTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MLTH2Odll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API NAMEdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API PDFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PREOSdll_TYPE)(INTEGER &); + typedef void (LIBRARY_API PRESSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API PSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PUREFLDdll_TYPE)(INTEGER &); + typedef void (LIBRARY_API QMASSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API QMOLEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETAGAdll_TYPE)(INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMIXdll_TYPE)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMODdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETREFdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + //typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*); + typedef void (LIBRARY_API SPECGRdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API SUBLPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SUBLTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURFTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURTENdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API THERM0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM3dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERMdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API TPRHOdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TRNPRPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API VIRBdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API VIRCdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API WMOLdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMASSdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMOLEdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - // pattern to follow: typedef void [compiler specific stuff] func_t(int, float); - - // extra function for setup - typedef void (LIBRARY_API RPVersion_t )( char* ); - typedef void (LIBRARY_API SETPATHdll_t)( const char* ); - // - typedef void (LIBRARY_API ABFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ABFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ACTVYdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API AGdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CCRITdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CP0dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CRITPdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CSATKdll_t)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CV2PKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CVCPKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CVCPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DBFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DDDPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DDDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DHD1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DHFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DIELECdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DOTFILLdll_t)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DPDD2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTKdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPTSATKdll_t)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DSFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API ENTHALdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ENTROdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ESFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API FGCTYdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); - typedef void (LIBRARY_API FPVdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API GERG04dll_t)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API GETFIJdll_t)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GETKTVdll_t)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GIBBSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API HSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API INFOdll_t)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API LIMITKdll_t)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API LIMITSdll_t)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); - typedef void (LIBRARY_API LIMITXdll_t)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API MELTPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MELTTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MLTH2Odll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API NAMEdll_t)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API PDFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PDFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PQFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PREOSdll_t)(INTEGER &); - typedef void (LIBRARY_API PRESSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API PSFL1dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PUREFLDdll_t)(INTEGER &); - typedef void (LIBRARY_API QMASSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API QMOLEdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATDdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATEdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATSdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETAGAdll_t)(INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETKTVdll_t)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMIXdll_t)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMODdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETREFdll_t)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - //typedef void (LIBRARY_API SETUPdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETUPdll_t)(INTEGER &,char*,char*,char*,INTEGER &,char*); - typedef void (LIBRARY_API SPECGRdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API SUBLPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SUBLTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURFTdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURTENdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TDFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TEFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API THERM0dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM3dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERMdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFL2dll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API TPRHOdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TQFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TRNPRPdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TSFLSHdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API VIRBdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API VIRCdll_t)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API WMOLdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMASSdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMOLEdll_t)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - - - //Declare the functions - RPVersion_t RPVersion; - SETPATHdll_t SETPATHdll; - ABFL1dll_t ABFL1dll; - ABFL2dll_t ABFL2dll; - ACTVYdll_t ACTVYdll; - AGdll_t AGdll; - CCRITdll_t CCRITdll; - CP0dll_t CP0dll; - CRITPdll_t CRITPdll; - CSATKdll_t CSATKdll; - CV2PKdll_t CV2PKdll; - CVCPKdll_t CVCPKdll; - CVCPdll_t CVCPdll; - DBDTdll_t DBDTdll; - DBFL1dll_t DBFL1dll; - DBFL2dll_t DBFL2dll; - DDDPdll_t DDDPdll; - DDDTdll_t DDDTdll; - DEFLSHdll_t DEFLSHdll; - DHD1dll_t DHD1dll; - DHFLSHdll_t DHFLSHdll; - DHFL1dll_t DHFL1dll; - DHFL2dll_t DHFL2dll; - DIELECdll_t DIELECdll; - DOTFILLdll_t DOTFILLdll; - DPDD2dll_t DPDD2dll; - DPDDKdll_t DPDDKdll; - DPDDdll_t DPDDdll; - DPDTKdll_t DPDTKdll; - DPDTdll_t DPDTdll; - DPTSATKdll_t DPTSATKdll; - DSFLSHdll_t DSFLSHdll; - DSFL1dll_t DSFL1dll; - DSFL2dll_t DSFL2dll; - ENTHALdll_t ENTHALdll; - ENTROdll_t ENTROdll; - ESFLSHdll_t ESFLSHdll; - FGCTYdll_t FGCTYdll; - FPVdll_t FPVdll; - GERG04dll_t GERG04dll; - GETFIJdll_t GETFIJdll; - GETKTVdll_t GETKTVdll; - GIBBSdll_t GIBBSdll; - HSFLSHdll_t HSFLSHdll; - INFOdll_t INFOdll; - LIMITKdll_t LIMITKdll; - LIMITSdll_t LIMITSdll; - LIMITXdll_t LIMITXdll; - MELTPdll_t MELTPdll; - MELTTdll_t MELTTdll; - MLTH2Odll_t MLTH2Odll; - NAMEdll_t NAMEdll; - PDFL1dll_t PDFL1dll; - PDFLSHdll_t PDFLSHdll; - PEFLSHdll_t PEFLSHdll; - PHFL1dll_t PHFL1dll; - PHFLSHdll_t PHFLSHdll; - PQFLSHdll_t PQFLSHdll; - PREOSdll_t PREOSdll; - PRESSdll_t PRESSdll; - PSFL1dll_t PSFL1dll; - PSFLSHdll_t PSFLSHdll; - PUREFLDdll_t PUREFLDdll; - QMASSdll_t QMASSdll; - QMOLEdll_t QMOLEdll; - SATDdll_t SATDdll; - SATEdll_t SATEdll; - SATHdll_t SATHdll; - SATPdll_t SATPdll; - SATSdll_t SATSdll; - SATTdll_t SATTdll; - SETAGAdll_t SETAGAdll; - SETKTVdll_t SETKTVdll; - SETMIXdll_t SETMIXdll; - SETMODdll_t SETMODdll; - SETREFdll_t SETREFdll; - SETUPdll_t SETUPdll; - SPECGRdll_t SPECGRdll; - SUBLPdll_t SUBLPdll; - SUBLTdll_t SUBLTdll; - SURFTdll_t SURFTdll; - SURTENdll_t SURTENdll; - TDFLSHdll_t TDFLSHdll; - TEFLSHdll_t TEFLSHdll; - THERM0dll_t THERM0dll; - THERM2dll_t THERM2dll; - THERM3dll_t THERM3dll; - THERMdll_t THERMdll; - THFLSHdll_t THFLSHdll; - TPFLSHdll_t TPFLSHdll; - TPFL2dll_t TPFL2dll; - TPRHOdll_t TPRHOdll; - TQFLSHdll_t TQFLSHdll; - TRNPRPdll_t TRNPRPdll; - TSFLSHdll_t TSFLSHdll; - VIRBdll_t VIRBdll; - VIRCdll_t VIRCdll; - WMOLdll_t WMOLdll; - XMASSdll_t XMASSdll; - XMOLEdll_t XMOLEdll; + //Declare the functions for direct access + RPVersion_TYPE RPVersion; + SETPATHdll_TYPE SETPATHdll; + ABFL1dll_TYPE ABFL1dll; + ABFL2dll_TYPE ABFL2dll; + ACTVYdll_TYPE ACTVYdll; + AGdll_TYPE AGdll; + CCRITdll_TYPE CCRITdll; + CP0dll_TYPE CP0dll; + CRITPdll_TYPE CRITPdll; + CSATKdll_TYPE CSATKdll; + CV2PKdll_TYPE CV2PKdll; + CVCPKdll_TYPE CVCPKdll; + CVCPdll_TYPE CVCPdll; + DBDTdll_TYPE DBDTdll; + DBFL1dll_TYPE DBFL1dll; + DBFL2dll_TYPE DBFL2dll; + DDDPdll_TYPE DDDPdll; + DDDTdll_TYPE DDDTdll; + DEFLSHdll_TYPE DEFLSHdll; + DHD1dll_TYPE DHD1dll; + DHFLSHdll_TYPE DHFLSHdll; + DHFL1dll_TYPE DHFL1dll; + DHFL2dll_TYPE DHFL2dll; + DIELECdll_TYPE DIELECdll; + DOTFILLdll_TYPE DOTFILLdll; + DPDD2dll_TYPE DPDD2dll; + DPDDKdll_TYPE DPDDKdll; + DPDDdll_TYPE DPDDdll; + DPDTKdll_TYPE DPDTKdll; + DPDTdll_TYPE DPDTdll; + DPTSATKdll_TYPE DPTSATKdll; + DSFLSHdll_TYPE DSFLSHdll; + DSFL1dll_TYPE DSFL1dll; + DSFL2dll_TYPE DSFL2dll; + ENTHALdll_TYPE ENTHALdll; + ENTROdll_TYPE ENTROdll; + ESFLSHdll_TYPE ESFLSHdll; + FGCTYdll_TYPE FGCTYdll; + FPVdll_TYPE FPVdll; + GERG04dll_TYPE GERG04dll; + GETFIJdll_TYPE GETFIJdll; + GETKTVdll_TYPE GETKTVdll; + GIBBSdll_TYPE GIBBSdll; + HSFLSHdll_TYPE HSFLSHdll; + INFOdll_TYPE INFOdll; + LIMITKdll_TYPE LIMITKdll; + LIMITSdll_TYPE LIMITSdll; + LIMITXdll_TYPE LIMITXdll; + MELTPdll_TYPE MELTPdll; + MELTTdll_TYPE MELTTdll; + MLTH2Odll_TYPE MLTH2Odll; + NAMEdll_TYPE NAMEdll; + PDFL1dll_TYPE PDFL1dll; + PDFLSHdll_TYPE PDFLSHdll; + PEFLSHdll_TYPE PEFLSHdll; + PHFL1dll_TYPE PHFL1dll; + PHFLSHdll_TYPE PHFLSHdll; + PQFLSHdll_TYPE PQFLSHdll; + PREOSdll_TYPE PREOSdll; + PRESSdll_TYPE PRESSdll; + PSFL1dll_TYPE PSFL1dll; + PSFLSHdll_TYPE PSFLSHdll; + PUREFLDdll_TYPE PUREFLDdll; + QMASSdll_TYPE QMASSdll; + QMOLEdll_TYPE QMOLEdll; + SATDdll_TYPE SATDdll; + SATEdll_TYPE SATEdll; + SATHdll_TYPE SATHdll; + SATPdll_TYPE SATPdll; + SATSdll_TYPE SATSdll; + SATTdll_TYPE SATTdll; + SETAGAdll_TYPE SETAGAdll; + SETKTVdll_TYPE SETKTVdll; + SETMIXdll_TYPE SETMIXdll; + SETMODdll_TYPE SETMODdll; + SETREFdll_TYPE SETREFdll; + SETUPdll_TYPE SETUPdll; + SPECGRdll_TYPE SPECGRdll; + SUBLPdll_TYPE SUBLPdll; + SUBLTdll_TYPE SUBLTdll; + SURFTdll_TYPE SURFTdll; + SURTENdll_TYPE SURTENdll; + TDFLSHdll_TYPE TDFLSHdll; + TEFLSHdll_TYPE TEFLSHdll; + THERM0dll_TYPE THERM0dll; + THERM2dll_TYPE THERM2dll; + THERM3dll_TYPE THERM3dll; + THERMdll_TYPE THERMdll; + THFLSHdll_TYPE THFLSHdll; + TPFLSHdll_TYPE TPFLSHdll; + TPFL2dll_TYPE TPFL2dll; + TPRHOdll_TYPE TPRHOdll; + TQFLSHdll_TYPE TQFLSHdll; + TRNPRPdll_TYPE TRNPRPdll; + TSFLSHdll_TYPE TSFLSHdll; + VIRBdll_TYPE VIRBdll; + VIRCdll_TYPE VIRCdll; + WMOLdll_TYPE WMOLdll; + XMASSdll_TYPE XMASSdll; + XMOLEdll_TYPE XMOLEdll; - //Define explicit function pointers - typedef RPVersion_t * RPVersion_ptr; - typedef SETPATHdll_t * SETPATHdll_ptr; - typedef ABFL1dll_t * ABFL1dll_ptr; - typedef ABFL2dll_t * ABFL2dll_ptr; - typedef ACTVYdll_t * ACTVYdll_ptr; - typedef AGdll_t * AGdll_ptr; - typedef CCRITdll_t * CCRITdll_ptr; - typedef CP0dll_t * CP0dll_ptr; - typedef CRITPdll_t * CRITPdll_ptr; - typedef CSATKdll_t * CSATKdll_ptr; - typedef CV2PKdll_t * CV2PKdll_ptr; - typedef CVCPKdll_t * CVCPKdll_ptr; - typedef CVCPdll_t * CVCPdll_ptr; - typedef DBDTdll_t * DBDTdll_ptr; - typedef DBFL1dll_t * DBFL1dll_ptr; - typedef DBFL2dll_t * DBFL2dll_ptr; - typedef DDDPdll_t * DDDPdll_ptr; - typedef DDDTdll_t * DDDTdll_ptr; - typedef DEFLSHdll_t * DEFLSHdll_ptr; - typedef DHD1dll_t * DHD1dll_ptr; - typedef DHFLSHdll_t * DHFLSHdll_ptr; - typedef DHFL1dll_t * DHFL1dll_ptr; - typedef DHFL2dll_t * DHFL2dll_ptr; - typedef DIELECdll_t * DIELECdll_ptr; - typedef DOTFILLdll_t * DOTFILLdll_ptr; - typedef DPDD2dll_t * DPDD2dll_ptr; - typedef DPDDKdll_t * DPDDKdll_ptr; - typedef DPDDdll_t * DPDDdll_ptr; - typedef DPDTKdll_t * DPDTKdll_ptr; - typedef DPDTdll_t * DPDTdll_ptr; - typedef DPTSATKdll_t * DPTSATKdll_ptr; - typedef DSFLSHdll_t * DSFLSHdll_ptr; - typedef DSFL1dll_t * DSFL1dll_ptr; - typedef DSFL2dll_t * DSFL2dll_ptr; - typedef ENTHALdll_t * ENTHALdll_ptr; - typedef ENTROdll_t * ENTROdll_ptr; - typedef ESFLSHdll_t * ESFLSHdll_ptr; - typedef FGCTYdll_t * FGCTYdll_ptr; - typedef FPVdll_t * FPVdll_ptr; - typedef GERG04dll_t * GERG04dll_ptr; - typedef GETFIJdll_t * GETFIJdll_ptr; - typedef GETKTVdll_t * GETKTVdll_ptr; - typedef GIBBSdll_t * GIBBSdll_ptr; - typedef HSFLSHdll_t * HSFLSHdll_ptr; - typedef INFOdll_t * INFOdll_ptr; - typedef LIMITKdll_t * LIMITKdll_ptr; - typedef LIMITSdll_t * LIMITSdll_ptr; - typedef LIMITXdll_t * LIMITXdll_ptr; - typedef MELTPdll_t * MELTPdll_ptr; - typedef MELTTdll_t * MELTTdll_ptr; - typedef MLTH2Odll_t * MLTH2Odll_ptr; - typedef NAMEdll_t * NAMEdll_ptr; - typedef PDFL1dll_t * PDFL1dll_ptr; - typedef PDFLSHdll_t * PDFLSHdll_ptr; - typedef PEFLSHdll_t * PEFLSHdll_ptr; - typedef PHFL1dll_t * PHFL1dll_ptr; - typedef PHFLSHdll_t * PHFLSHdll_ptr; - typedef PQFLSHdll_t * PQFLSHdll_ptr; - typedef PREOSdll_t * PREOSdll_ptr; - typedef PRESSdll_t * PRESSdll_ptr; - typedef PSFL1dll_t * PSFL1dll_ptr; - typedef PSFLSHdll_t * PSFLSHdll_ptr; - typedef PUREFLDdll_t * PUREFLDdll_ptr; - typedef QMASSdll_t * QMASSdll_ptr; - typedef QMOLEdll_t * QMOLEdll_ptr; - typedef SATDdll_t * SATDdll_ptr; - typedef SATEdll_t * SATEdll_ptr; - typedef SATHdll_t * SATHdll_ptr; - typedef SATPdll_t * SATPdll_ptr; - typedef SATSdll_t * SATSdll_ptr; - typedef SATTdll_t * SATTdll_ptr; - typedef SETAGAdll_t * SETAGAdll_ptr; - typedef SETKTVdll_t * SETKTVdll_ptr; - typedef SETMIXdll_t * SETMIXdll_ptr; - typedef SETMODdll_t * SETMODdll_ptr; - typedef SETREFdll_t * SETREFdll_ptr; - typedef SETUPdll_t * SETUPdll_ptr; - typedef SPECGRdll_t * SPECGRdll_ptr; - typedef SUBLPdll_t * SUBLPdll_ptr; - typedef SUBLTdll_t * SUBLTdll_ptr; - typedef SURFTdll_t * SURFTdll_ptr; - typedef SURTENdll_t * SURTENdll_ptr; - typedef TDFLSHdll_t * TDFLSHdll_ptr; - typedef TEFLSHdll_t * TEFLSHdll_ptr; - typedef THERM0dll_t * THERM0dll_ptr; - typedef THERM2dll_t * THERM2dll_ptr; - typedef THERM3dll_t * THERM3dll_ptr; - typedef THERMdll_t * THERMdll_ptr; - typedef THFLSHdll_t * THFLSHdll_ptr; - typedef TPFLSHdll_t * TPFLSHdll_ptr; - typedef TPFL2dll_t * TPFL2dll_ptr; - typedef TPRHOdll_t * TPRHOdll_ptr; - typedef TQFLSHdll_t * TQFLSHdll_ptr; - typedef TRNPRPdll_t * TRNPRPdll_ptr; - typedef TSFLSHdll_t * TSFLSHdll_ptr; - typedef VIRBdll_t * VIRBdll_ptr; - typedef VIRCdll_t * VIRCdll_ptr; - typedef WMOLdll_t * WMOLdll_ptr; - typedef XMASSdll_t * XMASSdll_ptr; - typedef XMOLEdll_t * XMOLEdll_ptr; + //Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; + typedef SPECGRdll_TYPE * SPECGRdll_POINTER; + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; - - #ifdef __cplusplus - } // extern "C" - #endif - -//#ifdef __cplusplus -//extern "C" { -//#endif -// routines used in henning francke's wrapper -// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, -// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD -// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 -// -////Define explicit function pointers -//fp_RPVersion RPVersion; -//fp_SETPATHdll SETPATHdll; -////Define explicit function pointers -//fp_ABFL1dll ABFL1dll; -//fp_ABFL2dll ABFL2dll; -//fp_ACTVYdll ACTVYdll; -//fp_AGdll AGdll; -//fp_CCRITdll CCRITdll; -//fp_CP0dll CP0dll; -//fp_CRITPdll CRITPdll; -//fp_CSATKdll CSATKdll; -//fp_CV2PKdll CV2PKdll; -//fp_CVCPKdll CVCPKdll; -//fp_CVCPdll CVCPdll; -//fp_DBDTdll DBDTdll; -//fp_DBFL1dll DBFL1dll; -//fp_DBFL2dll DBFL2dll; -//fp_DDDPdll DDDPdll; -//fp_DDDTdll DDDTdll; -//fp_DEFLSHdll DEFLSHdll; -//fp_DHD1dll DHD1dll; -//fp_DHFLSHdll DHFLSHdll; -//fp_DHFL1dll DHFL1dll; -//fp_DHFL2dll DHFL2dll; -//fp_DIELECdll DIELECdll; -//fp_DOTFILLdll DOTFILLdll; -//fp_DPDD2dll DPDD2dll; -//fp_DPDDKdll DPDDKdll; -//fp_DPDDdll DPDDdll; -//fp_DPDTKdll DPDTKdll; -//fp_DPDTdll DPDTdll; -//fp_DPTSATKdll DPTSATKdll; -//fp_DSFLSHdll DSFLSHdll; -//fp_DSFL1dll DSFL1dll; -//fp_DSFL2dll DSFL2dll; -//fp_ENTHALdll ENTHALdll; -//fp_ENTROdll ENTROdll; -//fp_ESFLSHdll ESFLSHdll; -//fp_FGCTYdll FGCTYdll; -//fp_FPVdll FPVdll; -//fp_GERG04dll GERG04dll; -//fp_GETFIJdll GETFIJdll; -//fp_GETKTVdll GETKTVdll; -//fp_GIBBSdll GIBBSdll; -//fp_HSFLSHdll HSFLSHdll; -//fp_INFOdll INFOdll; -//fp_LIMITKdll LIMITKdll; -//fp_LIMITSdll LIMITSdll; -//fp_LIMITXdll LIMITXdll; -//fp_MELTPdll MELTPdll; -//fp_MELTTdll MELTTdll; -//fp_MLTH2Odll MLTH2Odll; -//fp_NAMEdll NAMEdll; -//fp_PDFL1dll PDFL1dll; -//fp_PDFLSHdll PDFLSHdll; -//fp_PEFLSHdll PEFLSHdll; -//fp_PHFL1dll PHFL1dll; -//fp_PHFLSHdll PHFLSHdll; -//fp_PQFLSHdll PQFLSHdll; -//fp_PREOSdll PREOSdll; -//fp_PRESSdll PRESSdll; -//fp_PSFL1dll PSFL1dll; -//fp_PSFLSHdll PSFLSHdll; -//fp_PUREFLDdll PUREFLDdll; -//fp_QMASSdll QMASSdll; -//fp_QMOLEdll QMOLEdll; -//fp_SATDdll SATDdll; -//fp_SATEdll SATEdll; -//fp_SATHdll SATHdll; -//fp_SATPdll SATPdll; -//fp_SATSdll SATSdll; -//fp_SATTdll SATTdll; -//fp_SETAGAdll SETAGAdll; -//fp_SETKTVdll SETKTVdll; -//fp_SETMIXdll SETMIXdll; -//fp_SETMODdll SETMODdll; -//fp_SETREFdll SETREFdll; -//fp_SETUPdll SETUPdll; -//fp_SPECGRdll SPECGRdll; -//fp_SUBLPdll SUBLPdll; -//fp_SUBLTdll SUBLTdll; -//fp_SURFTdll SURFTdll; -//fp_SURTENdll SURTENdll; -//fp_TDFLSHdll TDFLSHdll; -//fp_TEFLSHdll TEFLSHdll; -//fp_THERM0dll THERM0dll; -//fp_THERM2dll THERM2dll; -//fp_THERM3dll THERM3dll; -//fp_THERMdll THERMdll; -//fp_THFLSHdll THFLSHdll; -//fp_TPFLSHdll TPFLSHdll; -//fp_TPFL2dll TPFL2dll; -//fp_TPRHOdll TPRHOdll; -//fp_TQFLSHdll TQFLSHdll; -//fp_TRNPRPdll TRNPRPdll; -//fp_TSFLSHdll TSFLSHdll; -//fp_VIRBdll VIRBdll; -//fp_VIRCdll VIRCdll; -//fp_WMOLdll WMOLdll; -//fp_XMASSdll XMASSdll; -//fp_XMOLEdll XMOLEdll; - -//#ifdef __cplusplus -//} // extern "C" -//#endif - - -//#ifdef __cplusplus -//extern "C" { -//#endif -// // extra function for setup -// void RPVersion ( char* ); -// void SETPATHdll( const char* ); -// // -// void ABFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void ABFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void ACTVYdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void AGdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void CCRITdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void CP0dll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void CRITPdll(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void CSATKdll(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void CV2PKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void CVCPKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void CVCPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void DBDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DBFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DBFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DDDPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DDDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DHD1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void DHFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke -// void DHFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke -// void DHFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DIELECdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DOTFILLdll(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DPDD2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DPDDKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void DPDDdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DPDTKdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void DPDTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void DPTSATKdll(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void DSFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke -// void DSFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke -// void ENTHALdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void ENTROdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void ESFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void FGCTYdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); -// void FPVdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void GERG04dll(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); -// void GETFIJdll(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); -// void GETKTVdll(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); -// void GIBBSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void HSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void INFOdll(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void LIMITKdll(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); -// void LIMITSdll(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); -// void LIMITXdll(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); -// void MELTPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void MELTTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void MLTH2Odll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void NAMEdll(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); -// void PDFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PDFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PHFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PHFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PQFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PREOSdll(INTEGER &); -// void PRESSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void PSFL1dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void PUREFLDdll(INTEGER &); -// void QMASSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void QMOLEdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SATDdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); -// void SATEdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SATHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SATPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); -// void SATSdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SATTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); -// void SETAGAdll(INTEGER &,char*,INTEGER ); -// void SETKTVdll(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); -// void SETMIXdll(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); -// void SETMODdll(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); -// void SETREFdll(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); -// //void SETUPdll(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); -// void SETUPdll(INTEGER &,char*,char*,char*,INTEGER &,char*); -// void SPECGRdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void SUBLPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SUBLTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SURFTdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void SURTENdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TDFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TEFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void THERM0dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void THERM2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void THERM3dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void THERMdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); -// void THFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TPFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TPFL2dll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke -// void TPRHOdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TQFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TRNPRPdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void TSFLSHdll(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); -// void VIRBdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void VIRCdll(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void WMOLdll(DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void XMASSdll(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -// void XMOLEdll(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); -//#ifdef __cplusplus -//} // extern "C" -//#endif +#ifdef __cplusplus +} // extern "C" +#endif // REFPROP_H #endif -// routines used in henning francke's wrapper -// setup, wmol, tpflsh, phflsh, PDFL1, PDFLSH, PSFLSH, PQFLSH, THFLSH, -// TDFLSH, TSFLSH, TQFLSH, DHFLSH, HSFLSH, DSFLSH, TRNPRP, SATT, SATP, SATD -// TPFL2, DHFL1, DHFL2, DSFL1, DSFL2 -// + diff --git a/readme.txt b/readme.md similarity index 60% rename from readme.txt rename to readme.md index 5d4435f..e94be43 100644 --- a/readme.txt +++ b/readme.md @@ -1,24 +1,23 @@ -Welcome to REFPROP2Modelica! - -This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the "Media" framework inside Modelica. It has only been tested with Dymola sofar. - -For Windows, please follow these instructions -1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". -2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) -3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ - -For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. -1. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. -2. Call "make libheader library" and "sudo make installlib" to compile and install refprop. -3. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. - -For both versions, the last step is the same: - -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). - Make sure you mask the backslashes. It should look something like - constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; - or - constant String REFPROP_PATH = "/home/user/Refprop/"; - - + +#Welcome to REFPROP2Modelica! +This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the "Media" framework inside Modelica. It has only been tested with Dymola sofar. + +## Installation Instructions + +### Windows +For Windows, please follow these instructions +1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". +2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) +3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; + +### Linux +For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. +2. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". +2. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. +3. Call "make libheader library" and "sudo make installlib" to compile and install refprop. +4. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; + +## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. \ No newline at end of file From 8c150013829cf57e859e9bb5a14b1138c998fc78 Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 2 Oct 2012 09:23:21 -0700 Subject: [PATCH 08/57] 2012:10:02 18:17 - Added Poco-framework in standard version, changed the readme, extended the makefile --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 62 ++++--- ...op_wrapper.cpp => refprop_wrapper.org.cpp} | 0 .../refprop_wrapper.poco.cpp | 160 +++++++++++++----- readme.md | 22 ++- 4 files changed, 166 insertions(+), 78 deletions(-) rename _REFPROP-Wrapper/Version 0.5_linux/{refprop_wrapper.cpp => refprop_wrapper.org.cpp} (100%) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index 5bb6255..d49d08b 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -14,9 +14,11 @@ # ============================================================================ # used for the output -THENAME =refprop -THEWRAPPER =refprop_wrapper -THETEST =refpropwrappertest +THENAME =refprop +THEWRAPPER =refprop_wrapper +THETEST =refpropwrappertest +LIBRARYEXTENSION =$(DYNAMICLIBRARYEXTENSION) +WRAPPEREXTENSION =$(DYNAMICLIBRARYEXTENSION) ########################################################### # Setting the directories for library, header and @@ -94,44 +96,44 @@ install : installlib installwrap .PHONY : installlib installlib : libheader library ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(LIBRARYEXTENSION) .PHONY : installwrap installwrap: wrapheader wrapper ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) .PHONY : uninstall uninstall : $(RM) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) $(LIBINST)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) $(RM) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) /usr/lib/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) /usr/lib/$(LIBRARY)$(LIBRARYEXTENSION) $(RM) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) $(RM) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + $(RM) /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) .PHONY : purge purge : cleanlib $(RM) $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(RM) $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) .PHONY : fixit fixit : install - ln -sf $(LIBINST)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(LIBINST)/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) - ln -sf /usr/lib/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) /usr/lib/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + ln -sf $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) $(LIBINST)/libREFPROP_wrapper$(WRAPPEREXTENSION) + ln -sf /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) /usr/lib/libREFPROP_wrapper$(WRAPPEREXTENSION) .PHONY : unfixit unfixit : - $(RM) $(LIBINST)/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) - $(RM) /usr/lib/libREFPROP_wrapper$(DYNAMICLIBRARYEXTENSION) + $(RM) $(LIBINST)/libREFPROP_wrapper$(WRAPPEREXTENSION) + $(RM) /usr/lib/libREFPROP_wrapper$(WRAPPEREXTENSION) .PHONY : removeall removeall : uninstall purge unfixit @@ -153,19 +155,24 @@ $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION): $(THEWRAPPER)$(HEADEREXTENSION) cp $(THEWRAPPER)$(HEADEREXTENSION) $(LIBDIR) .PHONY : wrapper -wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) -$(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader library - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).o -l$(THENAME) -lPocoFoundation +wrapper : poco +#wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) + +.PHONY : nopoco +nopoco : $(THEWRAPPER).o wrapheader libheader library + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).org.o -l$(THENAME) -lPocoFoundation + +.PHONY : poco +poco : $(THEWRAPPER).poco.o wrapheader libheader library + $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).poco.o -l$(THENAME) -lPocoFoundation -#.PHONY : wrapper -#wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) -#$(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader library -# ar -cvq $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) $(THEWRAPPER).o +#$(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader +# ar -cvq $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) $(THEWRAPPER).o src/$(LIBFILE).o $(LIBOBJECTFILES) .PHONY : test test : $(THETEST) $(THETEST) : $(THETEST).o wrapheader wrapper - $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o -l$(THEWRAPPER) + $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o -l$(THEWRAPPER) -lPocoFoundation ########################################################### # Compile the Fortran sources into a library file that can @@ -177,7 +184,8 @@ $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION): src/$(HEADERFILE)$(HEADEREXTENSION) cp src/$(HEADERFILE)$(HEADEREXTENSION) $(LIBDIR) .PHONY : library -library : $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) +library : $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) + $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION): src/$(LIBFILE).o $(LIBOBJECTFILES) $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) src/$(LIBFILE).o $(LIBOBJECTFILES) @@ -227,7 +235,7 @@ $(BINDIR)/RP-ftn : src/refprop-ftn.cpp libheader library .PHONY : f2f f2f : $(BINDIR)/f2f -$(BINDIR)/f2f : example/ex-mix.for $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) +$(BINDIR)/f2f : example/ex-mix.for $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(FC) $(FFLAGS) -o example/ex-mix.o -c example/ex-mix.for $(FC) $(FLINKFLAGS) -o $(BINDIR)/f2f example/ex-mix.o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.org.cpp similarity index 100% rename from _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.cpp rename to _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.org.cpp diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp index 548d4e5..d0ce770 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp @@ -45,6 +45,7 @@ #include "Poco/Path.h" #include "Poco/File.h" #include "Poco/Environment.h" +#include "Poco/StringTokenizer.h" #include "Poco/String.h" // Some constants... @@ -56,6 +57,7 @@ const long ncmax=20; // Note: ncmax is the max number of components //Poco::SharedLibrary RefpropdllInstance; char loadedfluids[refpropcharlength]; +char loadedpath[filepathlength]; //// Define the functions either by their pointers or type. //WMOLdll_POINTER WMOLdll; @@ -83,20 +85,26 @@ char loadedfluids[refpropcharlength]; //SATPdll_POINTER SATPdll; //SATDdll_POINTER SATDdll; - -char *str_replace(char *str, char *search, char *replace, long *count) { +//str_replace (fluidnames, "|", replace, nX) +char *str_replace(char *str, char *search, char *replace, long *count) { int i,n_ret; int newlen = strlen(replace); int oldlen = strlen(search); char *ret; *count = 0; - + //count occurrences of searchstring for (i = 0; oldlen && str[i]; ++i) if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr ++*count, i+=oldlen - 1; } - ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); + ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); +// std::string stri (&str); +// std::string sear (&search); +// Poco::StringTokenizer StrTok(stri,sear,Poco::StringTokenizer::TOK_TRIM); +// *count = StrTok.count(); +// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); + if (!ret){ printf("Could not allocate memory"); return ""; @@ -118,76 +126,140 @@ char *str_replace(char *str, char *search, char *replace, long *count) { } return ret; } +//char *str_replace(char *str, char *search, char *replace, long *count) { +// int i,n_ret; +// int newlen = strlen(replace); +// int oldlen = strlen(search); +// char *ret; +// *count = 0; +// +// //count occurrences of searchstring +// for (i = 0; oldlen && str[i]; ++i) +// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr +// ++*count, i+=oldlen - 1; +// } +// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); +// if (!ret){ +// printf("Could not allocate memory"); +// return ""; +// } +// +// if (!*count){ +// strncpy(ret,str,n_ret); +// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); +// }else{ +// i = 0; +// while (*str) +// if (strstr(str, search) == str) +// strncpy(&ret[i], replace,n_ret-i-1), +// i += newlen, +// str += oldlen; +// else +// ret[i++] = *str++; +// ret[i] = '\0'; +// } +// return ret; +//} -int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, char* errormsg, int DEBUGMODE){ +int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ // Sets up the interface to the REFPROP.DLL // is called by props_REFPROP and satprops_REFPROP // char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; long ierr=0; +// DEBUGMODE = 1; - if (strlen(REFPROP_PATH)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); + if (strlen(REFPROP_PATH_CHAR)>filepathlength){ + sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %i)\n",strlen(REFPROP_PATH_CHAR),filepathlength); return 0; } - - char* REFPROP_PATH_CHAR = REFPROP_PATH; - char* FLUIDS_CHAR = "fluids"; - char* LIBRARY_CHAR; - - - Poco::Path REF_PATH(true),FLD_PATH(true),LIB_PATH(true); // all paths will be absolute - + // Define temporary objects for checks. + char REF_PATH_CHAR[filepathlength]; + Poco::Path REF_PATH(true); + char FLUIDS_CHAR[filepathlength] = "fluids"; + Poco::Path FLD_PATH(true); + char LIBRARY_CHAR[filepathlength]; + Poco::Path LIB_PATH(true); + Poco::File theFile; + + // Parse the string and append a path separator if necessary. REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); - Poco::File theFile(REF_PATH); - if ( !theFile.isDirectory() || !theFile.canRead() ){ + // Overwrite the provided path + strcpy(REF_PATH_CHAR,REF_PATH.toString().c_str()); + + // Check the path if running in debugmode + if (DEBUGMODE) { + theFile = Poco::File(REF_PATH); + if ( !theFile.isDirectory() || !theFile.canRead() ){ sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); return 0; + } } - FLD_PATH.parse(REF_PATH.toString()); + // The fluid files are in the Refprop directory, append "fluids". + FLD_PATH.parse(REF_PATH_CHAR); FLD_PATH.pushDirectory(FLUIDS_CHAR); - LIB_PATH.parse(REF_PATH.toString()); - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - LIBRARY_CHAR = "librefprop.so"; + if (DEBUGMODE) { + // Determine which library file should be loaded + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + strcpy(LIBRARY_CHAR,"librefprop.so"); + } else { + strcpy(LIBRARY_CHAR,"refprop.dll"); + } + std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... + //std::string path(Poco::Environment::get("PATH")); + bool found_lib = Poco::Path::find(path, LIBRARY_CHAR, LIB_PATH); + if (found_lib) { + printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); + } else { + printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); + } } else { - LIBRARY_CHAR = "refprop.dll"; + LIB_PATH.parse(REF_PATH_CHAR); } - LIB_PATH.setFileName(LIBRARY_CHAR); - if (DEBUGMODE) printf ("Comparison of fluids : %i \n", strcmp(fluidnames,loadedfluids) ); -// if (DEBUGMODE) printf ("Comparison of library: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); + // Check for new fluids and if the library has to be loaded again. + if (DEBUGMODE) printf ("Comparison of fluids : %i \n", strcmp(fluidnames,loadedfluids) ); + if (DEBUGMODE) printf ("Comparison of path : %i \n", strcmp(REF_PATH_CHAR,loadedpath) ); + if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); + // if (strcmp(fluidnames,loadedfluids)==0) { -//// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())==0 ) { -//// sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); -// if (DEBUGMODE) printf ("Returning: %s and %s \n", RefpropdllInstance.getPath().c_str(),fluidnames ); +// if ( strcmp(REF_PATH_CHAR,loadedpath)==0 ) { +// sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); +// if (DEBUGMODE) printf ("No setup needed: %s and %s \n", REF_PATH_CHAR,loadedpath ); // return 0; -//// } +// } // } + strcpy(loadedpath,REF_PATH_CHAR); + if (DEBUGMODE) { printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); - printf ("Running on: %s \n", Poco::Environment::osName().c_str()); + printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); } - theFile = Poco::File(LIB_PATH); - if ( !theFile.isFile() || !theFile.canExecute() ){ - sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); - return 0; + if (DEBUGMODE) { + theFile = Poco::File(LIB_PATH); + if ( !theFile.isFile() || !theFile.canExecute() ){ + sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); + return 0; + } } char LIB_PATH_CHAR[filepathlength]; strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); + if (DEBUGMODE) { theFile = Poco::File(FLD_PATH); if ( !theFile.isDirectory() || !theFile.canRead() ){ sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); return 0; } + } char FLD_PATH_CHAR[filepathlength]; strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); @@ -212,7 +284,6 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, cha char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; char *hf; - strcpy(loadedfluids,fluidnames); //parse fluid composition string and insert absolute paths char replace[filepathlength+6]; strcpy(replace,".FLD|"); @@ -239,6 +310,7 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, cha // SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); if (DEBUGMODE) printf("Running SETUPdll...\n"); SETUPdll(*nX, hf, hfmix, hrf, ierr, herr); + strcpy(loadedfluids,fluidnames); if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); // WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); @@ -337,6 +409,8 @@ OUTPUT // HINSTANCE RefpropdllInstance;// Then have windows load the library. // Poco::SharedLibrary RefpropdllInstance(""); +// DEBUGMODE = 1; + if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); //initialize interface to REFPROP.dll @@ -420,12 +494,12 @@ OUTPUT TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); } }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); - PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ -// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); +// if (phase==1){ //fluid state is known to be single phase +//// PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); +// PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +//// if (liqvap==1) dl=d; else dv=d; +// }else{ +//// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); // } }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ @@ -588,6 +662,7 @@ OUTPUT break; case 211: sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; case 239: sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); break; @@ -706,6 +781,7 @@ OUTPUT // void* RefpropdllInstance; // Poco::SharedLibrary RefpropdllInstance(""); +// DEBUGMODE = 1; if (DEBUGMODE) printf("\nStarting function satprops_REFPROP...\n"); diff --git a/readme.md b/readme.md index e94be43..3e833ac 100644 --- a/readme.md +++ b/readme.md @@ -2,22 +2,26 @@ #Welcome to REFPROP2Modelica! This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the "Media" framework inside Modelica. It has only been tested with Dymola sofar. +Please be aware that you might need a copy of the Poco C++ framework to compile the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. + ## Installation Instructions ### Windows For Windows, please follow these instructions -1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". -2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) -3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; + +1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". +2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) +3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; ### Linux For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. -2. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". -2. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. -3. Call "make libheader library" and "sudo make installlib" to compile and install refprop. -4. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. -5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; + +1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". +2. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. +3. Call "make libheader library" and "sudo make installlib" to compile and install refprop. +4. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. \ No newline at end of file From a9995e5c67b1ba41f800cfd0aed5f8a748680fcf Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 24 Oct 2012 07:13:07 -0700 Subject: [PATCH 09/57] 2012:10:24 16:11 - Changed the folder structure, compiling Refprop is now handled externally (check the readme), cleaned the makefile. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 278 ++----- .../src/PASS_FTN_LIN.FOR.tpl | 68 -- .../Version 0.5_linux/src/refprop-ftn.cpp | 396 --------- .../Version 0.5_linux/src/refprop_lib.h | 779 ------------------ .../{ => src}/refprop_wrapper.h | 0 .../{ => src}/refprop_wrapper.org.cpp | 0 .../{ => src}/refprop_wrapper.poco.cpp | 0 .../{ => src}/refpropwrappertest.cpp | 2 +- readme.md | 12 +- 9 files changed, 92 insertions(+), 1443 deletions(-) delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h rename _REFPROP-Wrapper/Version 0.5_linux/{ => src}/refprop_wrapper.h (100%) rename _REFPROP-Wrapper/Version 0.5_linux/{ => src}/refprop_wrapper.org.cpp (100%) rename _REFPROP-Wrapper/Version 0.5_linux/{ => src}/refprop_wrapper.poco.cpp (100%) rename _REFPROP-Wrapper/Version 0.5_linux/{ => src}/refpropwrappertest.cpp (96%) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index d49d08b..4e02c08 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -1,251 +1,143 @@ # ============================================================================ # Name : Makefile # Author : Jorrit Wronski (jowr@mek.dtu.dk) -# Version : 0.2 +# Version : 0.3 # Copyright : Use and modify at your own risk. # Description : Makefile for Refprop from Fortran and C++ tests. # ============================================================================ # The installation procedure should be as follows: -# 1) make libheader library -# 2) sudo make installlib -# 3) make wrapheader wrapper -# 4) sudo make installwrap -# 5) sudo make fixit +# 0) make sure to have librefprop.so available on your system +# 1) make header library +# 2) sudo make install +# 3) sudo make fixit # ============================================================================ +# general commands: +RM := rm -f +CP := cp +CH := chmod 0644 +MK := mkdir -p +LD := ldconfig +LN := ln -sf # used for the output -THENAME =refprop -THEWRAPPER =refprop_wrapper +MAJORVERSION =0 +MINORVERSION =5 +THENAME =refprop_wrapper +LIBRARYEXTENSION =.so THETEST =refpropwrappertest -LIBRARYEXTENSION =$(DYNAMICLIBRARYEXTENSION) -WRAPPEREXTENSION =$(DYNAMICLIBRARYEXTENSION) ########################################################### # Setting the directories for library, header and # binary files created in this makefile. ########################################################### -LIBDIR =/home/jowr/Documents/Fluids/refprop/v9.0 -DYMDIR =/opt/dymola -LIBINST =$(DYMDIR)/bin/lib -HEADINST =$(DYMDIR)/source -BINDIR =. +SRCDIR =./src +# DYMDIR =/opt/dymola +# LIBINST =$(DYMDIR)/bin/lib +# HEADINST =$(DYMDIR)/source +LIBINST =/usr/local/lib +HEADINST =/usr/local/include +BINDIR =./bin -OPTFLAGS = -O3 -ffast-math# -ffloat-store # optimisation, remove for debugging -########################################################### -# Change these lines if you are using a different Fortran -# compiler or if you would like to use other flags. -########################################################### -FC =gfortran -FFLAGS =$(OPTFLAGS) -Wall -pedantic# -ff2c -fbounds-check -FLINKFLAGS =$(FFLAGS) + +LIBS =-lrefprop +OPTFLAGS =-O3 -ffast-math# -ffloat-store # optimisation, remove for debugging ########################################################### # Change these lines if you are using a different C++ # compiler or if you would like to use other flags. ########################################################### -CPPC =g++ -CPPFLAGS =$(OPTFLAGS) -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 +CPPC =g++ +CPPFLAGS =$(OPTFLAGS) -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 ########################################################### # Change these lines if you have other needs regarding -# the library file. +# the generated shared library file. ########################################################### -LIBFLAGS =-rdynamic -fPIC -shared -LIBRARY =lib$(THENAME) -LIBFILE =PASS_FTN_LIN -DYNAMICLIBRARYEXTENSION =.so -STATICLIBRARYEXTENSION =.a -#ar -cvq $(LIBRARY)$(STATICLIBRARYEXTENSION) $(OBJECTFILES) -HEADERFILE =$(THENAME)_lib -HEADEREXTENSION =.h -### List of files to compile -LIBOBJECTFILES = \ - $(LIBDIR)/fortran/SETUP.o \ - $(LIBDIR)/fortran/CORE_ANC.o \ - $(LIBDIR)/fortran/CORE_BWR.o \ - $(LIBDIR)/fortran/CORE_CPP.o \ - $(LIBDIR)/fortran/CORE_DE.o \ - $(LIBDIR)/fortran/CORE_ECS.o \ - $(LIBDIR)/fortran/CORE_FEQ.o \ - $(LIBDIR)/fortran/CORE_MLT.o \ - $(LIBDIR)/fortran/CORE_PH0.o \ - $(LIBDIR)/fortran/CORE_QUI.o \ - $(LIBDIR)/fortran/CORE_STN.o \ - $(LIBDIR)/fortran/CORE_PR.o \ - $(LIBDIR)/fortran/FLASH2.o \ - $(LIBDIR)/fortran/FLSH_SUB.o \ - $(LIBDIR)/fortran/IDEALGAS.o \ - $(LIBDIR)/fortran/MIX_AGA8.o \ - $(LIBDIR)/fortran/MIX_HMX.o \ - $(LIBDIR)/fortran/PROP_SUB.o \ - $(LIBDIR)/fortran/REALGAS.o \ - $(LIBDIR)/fortran/SAT_SUB.o \ - $(LIBDIR)/fortran/SETUP2.o \ - $(LIBDIR)/fortran/TRNS_ECS.o \ - $(LIBDIR)/fortran/TRNS_TCX.o \ - $(LIBDIR)/fortran/TRNS_VIS.o \ - $(LIBDIR)/fortran/TRNSP.o \ - $(LIBDIR)/fortran/UTILITY.o - +LIBFILE =$(THENAME) +LIBRARY =lib$(THENAME) +LIBFLAGS =-rdynamic -fPIC -shared -Wl,-soname,$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) +HEADERFILE =$(THENAME) +HEADEREXTENSION =.h + ########################################################### -# Link all files to places recognised by the system. +# Copy files to places recognised by the system. ########################################################### .PHONY : install -install : installlib installwrap - -.PHONY : installlib -installlib : libheader library - ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) - ln -sf $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) /usr/lib/$(LIBRARY)$(LIBRARYEXTENSION) - -.PHONY : installwrap -installwrap: wrapheader wrapper - ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) - ln -sf $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) - ln -sf $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) - +install : header library + $(MK) $(HEADINST) $(LIBINST) + $(CP) $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(CH) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CH) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(LD) -l $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(LN) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) + $(LD) + .PHONY : uninstall -uninstall : +uninstall : unfixit $(RM) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) - $(RM) /usr/include/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) /usr/lib/$(LIBRARY)$(LIBRARYEXTENSION) - $(RM) $(HEADINST)/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) - $(RM) /usr/include/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) - -.PHONY : purge -purge : cleanlib - $(RM) $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) - $(RM) $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) - $(RM) $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) - $(RM) $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) - + $(RM) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION)* + +.PHONY : all +all : header library + .PHONY : fixit fixit : install - ln -sf $(LIBINST)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) $(LIBINST)/libREFPROP_wrapper$(WRAPPEREXTENSION) - ln -sf /usr/lib/lib$(THEWRAPPER)$(WRAPPEREXTENSION) /usr/lib/libREFPROP_wrapper$(WRAPPEREXTENSION) + ln -sf $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) + ln -sf $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) .PHONY : unfixit unfixit : - $(RM) $(LIBINST)/libREFPROP_wrapper$(WRAPPEREXTENSION) - $(RM) /usr/lib/libREFPROP_wrapper$(WRAPPEREXTENSION) + $(RM) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) + $(RM) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) -.PHONY : removeall -removeall : uninstall purge unfixit +########################################################## +# Compile the C++ sources into a library file that can +# be used as a shared object. +########################################################### +.PHONY : header +header : $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) +$(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION): $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(BINDIR) -.PHONY : all -all : - make libheader library - sudo make installlib - make wrapheader wrapper - sudo make installwrap - sudo make fixit +.PHONY : library +library : $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) -########################################################### -# Compile the wrapper class and its tests. -########################################################### -.PHONY : wrapheader -wrapheader : $(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION) -$(LIBDIR)/$(THEWRAPPER)$(HEADEREXTENSION): $(THEWRAPPER)$(HEADEREXTENSION) - cp $(THEWRAPPER)$(HEADEREXTENSION) $(LIBDIR) - -.PHONY : wrapper -wrapper : poco -#wrapper : $(LIBDIR)/lib$(THEWRAPPER)$(WRAPPEREXTENSION) +$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): nopoco .PHONY : nopoco -nopoco : $(THEWRAPPER).o wrapheader libheader library - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).org.o -l$(THENAME) -lPocoFoundation +nopoco : $(SRCDIR)/$(LIBFILE).org.o + $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).org.o $(LIBS) .PHONY : poco -poco : $(THEWRAPPER).poco.o wrapheader libheader library - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/lib$(THEWRAPPER)$(DYNAMICLIBRARYEXTENSION) $(THEWRAPPER).poco.o -l$(THENAME) -lPocoFoundation - -#$(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION): $(THEWRAPPER).o wrapheader libheader -# ar -cvq $(LIBDIR)/lib$(THEWRAPPER)$(STATICLIBRARYEXTENSION) $(THEWRAPPER).o src/$(LIBFILE).o $(LIBOBJECTFILES) - -.PHONY : test -test : $(THETEST) -$(THETEST) : $(THETEST).o wrapheader wrapper - $(FC) $(FLINKFLAGS) -o $(THETEST) $(THETEST).o -l$(THEWRAPPER) -lPocoFoundation +poco : $(SRCDIR)/$(LIBFILE).poco.o + $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).poco.o $(LIBS) -lPocoFoundation ########################################################### -# Compile the Fortran sources into a library file that can -# be used as a shared object. -########################################################### -.PHONY : libheader -libheader : $(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION) -$(LIBDIR)/$(HEADERFILE)$(HEADEREXTENSION): src/$(HEADERFILE)$(HEADEREXTENSION) - cp src/$(HEADERFILE)$(HEADEREXTENSION) $(LIBDIR) - -.PHONY : library -library : $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) - -$(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION): src/$(LIBFILE).o $(LIBOBJECTFILES) - $(FC) $(LIBFLAGS) $(FLINKFLAGS) -o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) src/$(LIBFILE).o $(LIBOBJECTFILES) - -src/$(LIBFILE).FOR: $(LIBDIR)/fortran/PASS_FTN.FOR - sed 's/dll_export/!dll_export/g' $(LIBDIR)/fortran/PASS_FTN.FOR > src/$(LIBFILE).FOR - cat src/$(LIBFILE).FOR.tpl >> src/$(LIBFILE).FOR - -# sed -i 's/*10000/(10000)/g' src/$(LIBFILE).FOR -# sed -i 's/*255/(255)/g' src/$(LIBFILE).FOR +# Compile the wrapper class tests. +########################################################### +.PHONY : test +test : $(BINDIR)/$(THETEST) -$(LIBDIR)/fortran/%.o: $(LIBDIR)/fortran/%.FOR - $(FC) $(FFLAGS) -o $(LIBDIR)/fortran/$*.o -c $< +$(BINDIR)/$(THETEST) : $(SRCDIR)/$(THETEST).o + $(CPPC) $(CPPFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).o $(LIBS) -l$(THENAME) ########################################################### # General rulesets for compilation. ########################################################### -src/%.o : src/%.FOR - $(FC) $(FFLAGS) -o src/$*.o -c $< - -src/%.o : src/%.cpp - $(CPPC) $(CPPFLAGS) -o src/$*.o -c $< +$(SRCDIR)/%.o : $(SRCDIR)/%.cpp + $(CPPC) $(CPPFLAGS) -o $(SRCDIR)/$*.o -c $< + +$(SRCDIR)/%.o : $(SRCDIR)/%.c + $(CC) $(CFLAGS) -o $(SRCDIR)/$*.o -c $< -%.o : %.FOR - $(FC) $(FFLAGS) -o $*.o -c $< - -%.o : %.cpp - $(CPPC) $(CPPFLAGS) -o $*.o -c $< +$(SRCDIR)/%.o : $(SRCDIR)/%.FOR + $(FC) $(FFLAGS) -o $(SRCDIR)/$*.o -c $< .PHONY: clean clean: - $(RM) **.o **.so **.mod $(BINDIR)/RP-ftn src/$(LIBFILE).FOR $(THETEST) - -.PHONY : cleanlib -cleanlib : - $(RM) $(LIBDIR)/fortran/**.o - -########################################################### -# Compile a simple example to illustrate the connection -# between C++ and Fortran as well as the usage of the -# created library with Fortran sources. -########################################################### -.PHONY : RP-ftn -RP-ftn : $(BINDIR)/RP-ftn -$(BINDIR)/RP-ftn : src/refprop-ftn.cpp libheader library - $(CPPC) $(CPPFLAGS) -o src/refprop-ftn.o -c src/refprop-ftn.cpp - $(FC) $(FLINKFLAGS) -o $(BINDIR)/RP-ftn src/refprop-ftn.o -l$(THENAME) -lPocoFoundation - -.PHONY : f2f -f2f : $(BINDIR)/f2f -$(BINDIR)/f2f : example/ex-mix.for $(LIBDIR)/$(LIBRARY)$(LIBRARYEXTENSION) - $(FC) $(FFLAGS) -o example/ex-mix.o -c example/ex-mix.for - $(FC) $(FLINKFLAGS) -o $(BINDIR)/f2f example/ex-mix.o $(LIBDIR)/$(LIBRARY)$(DYNAMICLIBRARYEXTENSION) + $(RM) **.o **.so **.mod $(BINDIR)/* $(SRCDIR)/*.o -.PHONY : cpp2f -cpp2f : $(BINDIR)/cpp2f -$(BINDIR)/cpp2f : example/cpp2f.cpp example/easy_f.for - $(FC) $(FFLAGS) -o example/easy_f.o -c example/easy_f.for - $(CPPC) $(CPPFLAGS) -o example/cpp2f.o -c example/cpp2f.cpp - $(FC) $(FLINKFLAGS) -o $(BINDIR)/cpp2f example/cpp2f.o example/easy_f.o - ########################################################### # Create the documentation from annotations in the source # files with DOXYGEN, a configuration file is needed. diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl b/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl deleted file mode 100644 index edc83be..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/PASS_FTN_LIN.FOR.tpl +++ /dev/null @@ -1,68 +0,0 @@ -c ====================================================================== -c Adding new routines used in the Modelica interface. -c subroutine DHFL1 (rho,h,x,t,ierr,herr) -c subroutine DHFL2 (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) -c subroutine DSFL1 (rho,s,x,t,ierr,herr) -c subroutine DSFL2 (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) -c subroutine TPFL2 (t,p,z,Dl,Dv,x,y,q,ierr,herr) -c ====================================================================== - subroutine DHFL1dll (rho,h,x,t,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHFLSHdll"::DHFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHFLSHdll - !dll_export DHFLSHdll - dimension x(ncmax) - call DHFL1 (rho,h,x,t,ierr,herr) - end -c ====================================================================== - subroutine DHFL2dll (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DHFLSHdll"::DHFLSHdll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DHFLSHdll - !dll_export DHFLSHdll - dimension z(ncmax),x(ncmax),y(ncmax) - call DHFL2 (D,h,z,t,p,Dl,Dv,x,y,q,ierr,herr) - end -c ====================================================================== - subroutine DSFL1dll (rho,s,x,t,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DSFL1dll"::DSFL1dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DSFL1dll - !dll_export DSFL1dll - dimension x(ncmax) - call DSFL1 (rho,s,x,t,ierr,herr) - end -c ====================================================================== - subroutine DSFL2dll (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_DSFL2dll"::DSFL2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::DSFL2dll - !dll_export DSFL2dll - dimension z(ncmax),x(ncmax),y(ncmax) - call DSFL2 (d,s,z,t,p,Dl,Dv,x,y,q,ierr,herr) - end -c ====================================================================== - subroutine TPFL2dll (t,p,z,Dl,Dv,x,y,q,ierr,herr) - implicit double precision (a-h,o-z) - implicit integer (i-n) - parameter (ncmax=20) - character*255 herr -cDEC$ ATTRIBUTES DLLEXPORT, Alias: "_TPFL2dll"::TPFL2dll -cDEC$ ATTRIBUTES STDCALL, REFERENCE::TPFL2dll - !dll_export TPFL2dll - dimension z(ncmax),x(ncmax),y(ncmax) - call TPFL2 (t,p,z,Dl,Dv,x,y,q,ierr,herr) - end -c ====================================================================== \ No newline at end of file diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp deleted file mode 100644 index 24b9f8a..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop-ftn.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* - * ============================================================================ - * Name : refprop-ftn.cpp - * Author : Jorrit Wronski (jowr@mek.dtu.dk) - * Version : 0.1 - * Copyright : Use and modify at your own risk. - * Description : example for Fortran and CPP interoperation. This file is - * based on EX_C1.CPP by Chris Muzny and EX_C2.c by Ian Bell. - * The example files can be obtained online from NIST - * http://www.boulder.nist.gov/div838/theory/refprop/Frequently_asked_questions.htm - * ============================================================================ - */ - -#include -#include /* EXIT_SUCCESS */ -#include /* strlen, memset, memcpy, memchr */ -#include /* refprop header file */ - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif - -#define refpropcharlength 255 -#define filepathlength 255 -#define maxstringlength 10000 -#define lengthofreference 3 -#define errormessagelength 255 -#define ncmax 20 // Note: ncmax is the max number of components -#define numparams 72 -#define maxcoefs 50 - - -void newline() { - printf("%s","\n"); -} - -#include "Poco/SharedLibrary.h" -#include "Poco/Path.h" -#include "Poco/File.h" -#include "Poco/Environment.h" -#include "Poco/String.h" - - - -int main(int argc, char* argv[]) { - - static long i,ierr,info_index; - static double wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas; - static char hfld[maxstringlength+1],hrf[lengthofreference+1],herr[errormessagelength+1],hfm[refpropcharlength+1]; - static char v[refpropcharlength+1],hpth[filepathlength+1],errormsg[errormessagelength+1]; - - static double x[ncmax],xliq[ncmax],xvap[ncmax],f[ncmax]; - - double t=100.0; - double p,dl,dv; - - char* REFPROP_PATH_CHAR = "/home/jowr/Documents/Fluids/refprop/v9.0"; - char* FLUIDS_CHAR = "fluids"; - char* LIBRARY_CHAR; - - - Poco::Path REFPROP_PATH(true),FLD_PATH(true),LIB_PATH(true); // all paths will be absolute - - REFPROP_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); - if (!REFPROP_PATH.isDirectory()) REFPROP_PATH.append(REFPROP_PATH.separator()); - Poco::File theFile(REFPROP_PATH); - if ( !theFile.isDirectory() || !theFile.canRead() ){ - printf ("REFPROP_PATH is not a readable directory: %s \n", REFPROP_PATH.toString().c_str()); - return 1; - } - - FLD_PATH.parse(REFPROP_PATH.toString()); - FLD_PATH.pushDirectory(FLUIDS_CHAR); - - LIB_PATH.parse(REFPROP_PATH.toString()); - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - LIBRARY_CHAR = "librefprop.so"; - } else { - LIBRARY_CHAR = "refprop.dll"; - } - LIB_PATH.setFileName(LIBRARY_CHAR); - - printf ("REFPROP_PATH as string: %s \n", REFPROP_PATH.toString().c_str()); - printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); - printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); - printf ("Running on: %s \n", Poco::Environment::osName().c_str()); - - theFile = Poco::File(LIB_PATH); - if ( !theFile.isFile() || !theFile.canExecute() ){ - printf ("LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); - return 1; - } - - theFile = Poco::File(FLD_PATH); - if ( !theFile.isDirectory() || !theFile.canRead() ){ - printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return 1; - } - -// First we load the library with the POCO foundation -// classes and then define all the needed functions -// by their names and a cast to the correct type. - Poco::SharedLibrary library(LIB_PATH.toString()); // will also load the library - -// Define the functions either by their pointers or type. - RPVersion_POINTER RPVersion = (RPVersion_POINTER) library.getSymbol(RPVersion_NAME); -// RPVersion_TYPE * RPVersion = (RPVersion_TYPE * ) library.getSymbol(RPVersion_NAME); - SETPATHdll_TYPE * SETPATHdll = (SETPATHdll_TYPE *) library.getSymbol(SETPATHdll_NAME); - ABFL1dll_TYPE * ABFL1dll = (ABFL1dll_TYPE * ) library.getSymbol(ABFL1dll_NAME); - ABFL2dll_TYPE * ABFL2dll = (ABFL2dll_TYPE * ) library.getSymbol(ABFL2dll_NAME); - ACTVYdll_TYPE * ACTVYdll = (ACTVYdll_TYPE * ) library.getSymbol(ACTVYdll_NAME); - AGdll_TYPE * AGdll = (AGdll_TYPE * ) library.getSymbol(AGdll_NAME); - CCRITdll_TYPE * CCRITdll = (CCRITdll_TYPE * ) library.getSymbol(CCRITdll_NAME); - CP0dll_TYPE * CP0dll = (CP0dll_TYPE * ) library.getSymbol(CP0dll_NAME); - CRITPdll_TYPE * CRITPdll = (CRITPdll_TYPE * ) library.getSymbol(CRITPdll_NAME); - CSATKdll_TYPE * CSATKdll = (CSATKdll_TYPE * ) library.getSymbol(CSATKdll_NAME); - CV2PKdll_TYPE * CV2PKdll = (CV2PKdll_TYPE * ) library.getSymbol(CV2PKdll_NAME); - CVCPKdll_TYPE * CVCPKdll = (CVCPKdll_TYPE * ) library.getSymbol(CVCPKdll_NAME); - CVCPdll_TYPE * CVCPdll = (CVCPdll_TYPE * ) library.getSymbol(CVCPdll_NAME); - DBDTdll_TYPE * DBDTdll = (DBDTdll_TYPE * ) library.getSymbol(DBDTdll_NAME); - DBFL1dll_TYPE * DBFL1dll = (DBFL1dll_TYPE * ) library.getSymbol(DBFL1dll_NAME); - DBFL2dll_TYPE * DBFL2dll = (DBFL2dll_TYPE * ) library.getSymbol(DBFL2dll_NAME); - DDDPdll_TYPE * DDDPdll = (DDDPdll_TYPE * ) library.getSymbol(DDDPdll_NAME); - DDDTdll_TYPE * DDDTdll = (DDDTdll_TYPE * ) library.getSymbol(DDDTdll_NAME); - DEFLSHdll_TYPE * DEFLSHdll = (DEFLSHdll_TYPE * ) library.getSymbol(DEFLSHdll_NAME); - DHD1dll_TYPE * DHD1dll = (DHD1dll_TYPE * ) library.getSymbol(DHD1dll_NAME); - DHFLSHdll_TYPE * DHFLSHdll = (DHFLSHdll_TYPE * ) library.getSymbol(DHFLSHdll_NAME); - DHFL1dll_TYPE * DHFL1dll = (DHFL1dll_TYPE * ) library.getSymbol(DHFL1dll_NAME); - DHFL2dll_TYPE * DHFL2dll = (DHFL2dll_TYPE * ) library.getSymbol(DHFL2dll_NAME); - DIELECdll_TYPE * DIELECdll = (DIELECdll_TYPE * ) library.getSymbol(DIELECdll_NAME); - DOTFILLdll_TYPE * DOTFILLdll = (DOTFILLdll_TYPE *) library.getSymbol(DOTFILLdll_NAME); - DPDD2dll_TYPE * DPDD2dll = (DPDD2dll_TYPE * ) library.getSymbol(DPDD2dll_NAME); - DPDDKdll_TYPE * DPDDKdll = (DPDDKdll_TYPE * ) library.getSymbol(DPDDKdll_NAME); - DPDDdll_TYPE * DPDDdll = (DPDDdll_TYPE * ) library.getSymbol(DPDDdll_NAME); - DPDTKdll_TYPE * DPDTKdll = (DPDTKdll_TYPE * ) library.getSymbol(DPDTKdll_NAME); - DPDTdll_TYPE * DPDTdll = (DPDTdll_TYPE * ) library.getSymbol(DPDTdll_NAME); - DPTSATKdll_TYPE * DPTSATKdll = (DPTSATKdll_TYPE *) library.getSymbol(DPTSATKdll_NAME); - DSFLSHdll_TYPE * DSFLSHdll = (DSFLSHdll_TYPE * ) library.getSymbol(DSFLSHdll_NAME); - DSFL1dll_TYPE * DSFL1dll = (DSFL1dll_TYPE * ) library.getSymbol(DSFL1dll_NAME); - DSFL2dll_TYPE * DSFL2dll = (DSFL2dll_TYPE * ) library.getSymbol(DSFL2dll_NAME); - ENTHALdll_TYPE * ENTHALdll = (ENTHALdll_TYPE * ) library.getSymbol(ENTHALdll_NAME); - ENTROdll_TYPE * ENTROdll = (ENTROdll_TYPE * ) library.getSymbol(ENTROdll_NAME); - ESFLSHdll_TYPE * ESFLSHdll = (ESFLSHdll_TYPE * ) library.getSymbol(ESFLSHdll_NAME); - FGCTYdll_TYPE * FGCTYdll = (FGCTYdll_TYPE * ) library.getSymbol(FGCTYdll_NAME); - FPVdll_TYPE * FPVdll = (FPVdll_TYPE * ) library.getSymbol(FPVdll_NAME); - GERG04dll_TYPE * GERG04dll = (GERG04dll_TYPE * ) library.getSymbol(GERG04dll_NAME); - GETFIJdll_TYPE * GETFIJdll = (GETFIJdll_TYPE * ) library.getSymbol(GETFIJdll_NAME); - GETKTVdll_TYPE * GETKTVdll = (GETKTVdll_TYPE * ) library.getSymbol(GETKTVdll_NAME); - GIBBSdll_TYPE * GIBBSdll = (GIBBSdll_TYPE * ) library.getSymbol(GIBBSdll_NAME); - HSFLSHdll_TYPE * HSFLSHdll = (HSFLSHdll_TYPE * ) library.getSymbol(HSFLSHdll_NAME); - INFOdll_TYPE * INFOdll = (INFOdll_TYPE * ) library.getSymbol(INFOdll_NAME); - LIMITKdll_TYPE * LIMITKdll = (LIMITKdll_TYPE * ) library.getSymbol(LIMITKdll_NAME); - LIMITSdll_TYPE * LIMITSdll = (LIMITSdll_TYPE * ) library.getSymbol(LIMITSdll_NAME); - LIMITXdll_TYPE * LIMITXdll = (LIMITXdll_TYPE * ) library.getSymbol(LIMITXdll_NAME); - MELTPdll_TYPE * MELTPdll = (MELTPdll_TYPE * ) library.getSymbol(MELTPdll_NAME); - MELTTdll_TYPE * MELTTdll = (MELTTdll_TYPE * ) library.getSymbol(MELTTdll_NAME); - MLTH2Odll_TYPE * MLTH2Odll = (MLTH2Odll_TYPE * ) library.getSymbol(MLTH2Odll_NAME); - NAMEdll_TYPE * NAMEdll = (NAMEdll_TYPE * ) library.getSymbol(NAMEdll_NAME); - PDFL1dll_TYPE * PDFL1dll = (PDFL1dll_TYPE * ) library.getSymbol(PDFL1dll_NAME); - PDFLSHdll_TYPE * PDFLSHdll = (PDFLSHdll_TYPE * ) library.getSymbol(PDFLSHdll_NAME); - PEFLSHdll_TYPE * PEFLSHdll = (PEFLSHdll_TYPE * ) library.getSymbol(PEFLSHdll_NAME); - PHFL1dll_TYPE * PHFL1dll = (PHFL1dll_TYPE * ) library.getSymbol(PHFL1dll_NAME); - PHFLSHdll_TYPE * PHFLSHdll = (PHFLSHdll_TYPE * ) library.getSymbol(PHFLSHdll_NAME); - PQFLSHdll_TYPE * PQFLSHdll = (PQFLSHdll_TYPE * ) library.getSymbol(PQFLSHdll_NAME); - PREOSdll_TYPE * PREOSdll = (PREOSdll_TYPE * ) library.getSymbol(PREOSdll_NAME); - PRESSdll_TYPE * PRESSdll = (PRESSdll_TYPE * ) library.getSymbol(PRESSdll_NAME); - PSFL1dll_TYPE * PSFL1dll = (PSFL1dll_TYPE * ) library.getSymbol(PSFL1dll_NAME); - PSFLSHdll_TYPE * PSFLSHdll = (PSFLSHdll_TYPE * ) library.getSymbol(PSFLSHdll_NAME); - PUREFLDdll_TYPE * PUREFLDdll = (PUREFLDdll_TYPE *) library.getSymbol(PUREFLDdll_NAME); - QMASSdll_TYPE * QMASSdll = (QMASSdll_TYPE * ) library.getSymbol(QMASSdll_NAME); - QMOLEdll_TYPE * QMOLEdll = (QMOLEdll_TYPE * ) library.getSymbol(QMOLEdll_NAME); - SATDdll_TYPE * SATDdll = (SATDdll_TYPE * ) library.getSymbol(SATDdll_NAME); - SATEdll_TYPE * SATEdll = (SATEdll_TYPE * ) library.getSymbol(SATEdll_NAME); - SATHdll_TYPE * SATHdll = (SATHdll_TYPE * ) library.getSymbol(SATHdll_NAME); - SATPdll_TYPE * SATPdll = (SATPdll_TYPE * ) library.getSymbol(SATPdll_NAME); - SATSdll_TYPE * SATSdll = (SATSdll_TYPE * ) library.getSymbol(SATSdll_NAME); - SATTdll_TYPE * SATTdll = (SATTdll_TYPE * ) library.getSymbol(SATTdll_NAME); - SETAGAdll_TYPE * SETAGAdll = (SETAGAdll_TYPE * ) library.getSymbol(SETAGAdll_NAME); - SETKTVdll_TYPE * SETKTVdll = (SETKTVdll_TYPE * ) library.getSymbol(SETKTVdll_NAME); - SETMIXdll_TYPE * SETMIXdll = (SETMIXdll_TYPE * ) library.getSymbol(SETMIXdll_NAME); - SETMODdll_TYPE * SETMODdll = (SETMODdll_TYPE * ) library.getSymbol(SETMODdll_NAME); - SETREFdll_TYPE * SETREFdll = (SETREFdll_TYPE * ) library.getSymbol(SETREFdll_NAME); - SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) library.getSymbol(SETUPdll_NAME); -// SPECGRdll_TYPE * SPECGRdll = (SPECGRdll_TYPE * ) library.getSymbol(SPECGRdll_NAME); - SUBLPdll_TYPE * SUBLPdll = (SUBLPdll_TYPE * ) library.getSymbol(SUBLPdll_NAME); - SUBLTdll_TYPE * SUBLTdll = (SUBLTdll_TYPE * ) library.getSymbol(SUBLTdll_NAME); - SURFTdll_TYPE * SURFTdll = (SURFTdll_TYPE * ) library.getSymbol(SURFTdll_NAME); - SURTENdll_TYPE * SURTENdll = (SURTENdll_TYPE * ) library.getSymbol(SURTENdll_NAME); - TDFLSHdll_TYPE * TDFLSHdll = (TDFLSHdll_TYPE * ) library.getSymbol(TDFLSHdll_NAME); - TEFLSHdll_TYPE * TEFLSHdll = (TEFLSHdll_TYPE * ) library.getSymbol(TEFLSHdll_NAME); - THERM0dll_TYPE * THERM0dll = (THERM0dll_TYPE * ) library.getSymbol(THERM0dll_NAME); - THERM2dll_TYPE * THERM2dll = (THERM2dll_TYPE * ) library.getSymbol(THERM2dll_NAME); - THERM3dll_TYPE * THERM3dll = (THERM3dll_TYPE * ) library.getSymbol(THERM3dll_NAME); - THERMdll_TYPE * THERMdll = (THERMdll_TYPE * ) library.getSymbol(THERMdll_NAME); - THFLSHdll_TYPE * THFLSHdll = (THFLSHdll_TYPE * ) library.getSymbol(THFLSHdll_NAME); - TPFLSHdll_TYPE * TPFLSHdll = (TPFLSHdll_TYPE * ) library.getSymbol(TPFLSHdll_NAME); - TPFL2dll_TYPE * TPFL2dll = (TPFL2dll_TYPE * ) library.getSymbol(TPFL2dll_NAME); - TPRHOdll_TYPE * TPRHOdll = (TPRHOdll_TYPE * ) library.getSymbol(TPRHOdll_NAME); - TQFLSHdll_TYPE * TQFLSHdll = (TQFLSHdll_TYPE * ) library.getSymbol(TQFLSHdll_NAME); - TRNPRPdll_TYPE * TRNPRPdll = (TRNPRPdll_TYPE * ) library.getSymbol(TRNPRPdll_NAME); - TSFLSHdll_TYPE * TSFLSHdll = (TSFLSHdll_TYPE * ) library.getSymbol(TSFLSHdll_NAME); - VIRBdll_TYPE * VIRBdll = (VIRBdll_TYPE * ) library.getSymbol(VIRBdll_NAME); - VIRCdll_TYPE * VIRCdll = (VIRCdll_TYPE * ) library.getSymbol(VIRCdll_NAME); - WMOLdll_TYPE * WMOLdll = (WMOLdll_TYPE * ) library.getSymbol(WMOLdll_NAME); - XMASSdll_TYPE * XMASSdll = (XMASSdll_TYPE * ) library.getSymbol(XMASSdll_NAME); - XMOLEdll_TYPE * XMOLEdll = (XMOLEdll_TYPE * ) library.getSymbol(XMOLEdll_NAME); - - - newline(); - - RPVersion(v); - printf("RPVersion(v) returned v = %s\n", v); - - strcpy(hpth,REFPROP_PATH.toString().c_str()); - SETPATHdll(hpth); - printf("SETPATHdll(hpth) called with hpth = %s\n", hpth); - - i=1; - strcpy(hfld,"nitrogen.fld"); - strcpy(hfm,"hmx.bnc"); - strcpy(hrf,"DEF"); - strcpy(herr,"Ok"); - SETUPdll(i,hfld,hfm,hrf,ierr,herr); - if (ierr != 0) printf("%s\n",herr); - printf("SETUPdll(i,hfld,hfm,hrf,ierr,herr) called with hfld = %s\n", hfld); - - info_index = 1; - INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas); - printf("INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas) called with index = %l\n", info_index); - printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); - printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); - - //...For a mixture, use the following setup instead of the lines above. - // Use "|" as the file name delimiter for mixtures - i=3; - strcpy(hfld,"nitrogen.fld"); - strcat(hfld,"|argon.fld"); - strcat(hfld,"|oxygen.fld"); - strcpy(hfm,"hmx.bnc"); - strcpy(hrf,"DEF"); - strcpy(herr,"Ok"); - x[0]=.7812; //Air composition - x[1]=.0092; - x[2]=.2096; - //...Call SETUP to initialize the program - SETUPdll(i,hfld,hfm,hrf,ierr,herr); - newline(); - printf("SETUPdll(i,hfld,hfm,hrf,ierr,herr) called with hfld = %s\n", hfld); - - INFOdll(info_index,wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas); - printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); - printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); - - //...Calculate molecular weight of a mixture - wm = 0.; - WMOLdll(x,wm); - newline(); - printf("wm %10.4f\n",wm); - - //...Get saturation properties given t,x; for i=1: x is liquid phase - //..... for i=2: x is vapor phase - - SATTdll(t,x,i,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); - i=2; - SATTdll(t,x,i,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); - - //...Calculate saturation properties at a given p. i is same as SATT - i=2; - SATPdll(p,x,i,t,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - printf("T,Dl,Dv,xl(1),xv(1) %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,dl,dv,xliq[0],xvap[0]); - - //...Other saturation routines are given in SAT_SUB.FOR - t=300.0; - p=20000.0; - - //...Calculate d from t,p,x - //...If phase is known: (j=1: Liquid, j=2: Vapor) - long j=1; - double d,q,e,h,s,cv,cp,w,b,c, - dpdrho,d2pdd2,dpdt,dhdt_d,dhdt_p,dhdp_t,dhdp_d, - sigma,dhdd_t,dhdd_p,eta,tcx,pp,tt,hjt,h1,dd; - long tmp_int=0; - TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); - printf("T,P,D %10.4f,%10.4f,%10.4f\n",t,p,d); - - //...If phase is not known, call TPFLSH - //...Calls to TPFLSH are much slower than TPRHO since SATT must be called first. - //.....(If two phase, quality is returned as q) - TPFLSHdll(t,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T,P,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,p,d,h,cp); - - //...Calculate pressure (p), internal energy (e), enthalpy (h), entropy (s), - //.....isochoric (cv) and isobaric (cp) heat capacities, speed of sound (w), - //.....and Joule-Thomson coefficient (hjt) from t,d,x - //.....(subroutines THERM2 and THERM3 contain more properties, see PROP_SUB.FOR) - THERMdll(t,d,x,p,e,h,s,cv,cp,w,hjt); - - //...Calculate pressure - PRESSdll(t,d,x,p); - - //...Calculate fugacity - FGCTYdll(t,d,x,f); - - //...Calculate second and third virial coefficients - VIRBdll (t,x,b); - VIRCdll (t,x,c); - printf("F,B,C %10.4f,%10.4f,%10.4f\n",f[0],b,c); - - //...Calculate the derivatives: dP/dD, d^2P/dD^2, dP/dT (D indicates density) - //...(dD/dP, dD/dT, and dB/dT are also available, see PROP_SUB.FOR) - DPDDdll (t,d,x,dpdrho); - DPDD2dll (t,d,x,d2pdd2); - DPDTdll (t,d,x,dpdt); - printf("dP/dD,d2P/dD2,dP/dT %10.4f,%10.4f,%10.4f\n",dpdrho,d2pdd2,dpdt); - - - //...Calculate derivatives of enthalpy with respect to T, P, and D - DHD1dll(t,d,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d); - printf("Enthalpy derivatives %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n", - dhdt_d,dhdt_p,dhdd_t,dhdd_p/1000.0,dhdp_t); - //...Calculate surface tension - SURFTdll (t,dl,x,sigma,ierr,herr,errormessagelength); - printf("T,SURF. TN. %10.4f,%10.4f\n",t,sigma); - - //...Calculate viscosity (eta) and thermal conductivity (tcx) - TRNPRPdll (t,d,x,eta,tcx,ierr,herr,errormessagelength); - printf("VIS.,TH.CND. %10.4f,%10.4f\n",eta,tcx*1000.0); - - //...General property calculation with inputs of t,d,x - TDFLSHdll (t,d,x,pp,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from TDFLSH %10.4f,%10.4f,%10.4f\n",t,d,pp/1000.0); - - //...General property calculation with inputs of p,d,x - PDFLSHdll (p,d,x,tt,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from PDFLSH %10.4f,%10.4f,%10.4f\n",tt,d,p/1000.0); - - //...General property calculation with inputs of p,h,x - PHFLSHdll (p,h,x,tt,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from PHFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); - - //...General property calculation with inputs of p,s,x - PSFLSHdll (p,s,x,tt,dd,dl,dv,xliq,xvap,q,e,h1,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from PSFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); - - //...General property calculation with inputs of d,h,x - DHFLSHdll (d,h,x,tt,pp,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from DHFLSH %10.4f,%10.4f,%10.4f\n",tt,d,pp/1000.0); - - //...General property calculation with inputs of t,h,x - // kr--flag specifying desired root for multi-valued inputs: - // 1=return lower density root - // 2=return higher density root - long kr=1; - THFLSHdll (t,h,x, - kr,pp,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - printf("T, D, P from THFLSH %10.4f,%10.4f,%10.4f\n",t,dd,pp/1000.0); - - //...Other general property calculation routines are given in FLSH_SUB.FOR - //...and FLASH2.FOR - - //...Calculate melting pressure - t=100.0; - MELTTdll (t,x,p,ierr,herr,errormessagelength); - printf("Melting pressure(MPa) %10.4f,%10.4f\n",p/1000.0,t); - - //...Calculate melting temperature - MELTPdll (p,x,tt,ierr,herr,errormessagelength); - printf("Melting temperature(K)%10.4f,%10.4f\n",tt,p/1000.0); - - //...Calculate sublimation pressure - t=200.0; - SUBLTdll (t,x,p,ierr,herr,errormessagelength); - printf("Sublimation pr.(kPa) %10.4f,%10.4f\n",p,t); - - //...Calculate sublimation temperature - SUBLPdll (p,x,tt,ierr,herr,errormessagelength); - printf("Sublimation temp.(K) %10.4f,%10.4f\n",tt,p); - - //...Get limits of the equations and check if t,d,p is a valid point - //...Equation of state - // call LIMITK ('EOS',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) - //...Viscosity equation - // call LIMITK ('ETA',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) - //...Thermal conductivity equation - // call LIMITK ('TCX',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) - - //...Other routines are given in UTILITY.FOR - - library.unload(); - -return EXIT_SUCCESS; -} - diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h deleted file mode 100644 index dec78c1..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_lib.h +++ /dev/null @@ -1,779 +0,0 @@ -#ifndef REFPROP_H -#define REFPROP_H -// -#include - -// Define data types that match the Fortran definitions. This is also -// a possible starting point to introduce platform independence. -// Partly taken from: http://arnholm.org/software/cppf77/cppf77.htm#Section5 -// An issue with characters still needs to be solved. -//#include -// The other data types can be handled: -typedef long INTEGER; -typedef float REAL; -typedef double DOUBLE_PRECISION; -typedef int LOGICAL; - -// Do some manual changes to the function names -// if needed. -#if defined(WIN32) || defined(_WIN32) -// Define compiler specific calling conventions -// for the shared library. -# define LIBRARY_API __stdcall // __declspec(dllexport) -// Do not define function names for the shared library, -// in this case it is the REFPROP.dll and no special -// names are needed. -# define RPVersion RPVersion -# define SETPATHdll SETPATHdll -# define ABFL1dll ABFL1dll -# define ABFL2dll ABFL2dll -# define ACTVYdll ACTVYdll -# define AGdll AGdll -# define CCRITdll CCRITdll -# define CP0dll CP0dll -# define CRITPdll CRITPdll -# define CSATKdll CSATKdll -# define CV2PKdll CV2PKdll -# define CVCPKdll CVCPKdll -# define CVCPdll CVCPdll -# define DBDTdll DBDTdll -# define DBFL1dll DBFL1dll -# define DBFL2dll DBFL2dll -# define DDDPdll DDDPdll -# define DDDTdll DDDTdll -# define DEFLSHdll DEFLSHdll -# define DHD1dll DHD1dll -# define DHFL1dll DHFL1dll -# define DHFL2dll DHFL2dll -# define DHFLSHdll DHFLSHdll -# define DIELECdll DIELECdll -# define DOTFILLdll DOTFILLdll -# define DPDD2dll DPDD2dll -# define DPDDKdll DPDDKdll -# define DPDDdll DPDDdll -# define DPDTKdll DPDTKdll -# define DPDTdll DPDTdll -# define DPTSATKdll DPTSATKdll -# define DSFLSHdll DSFLSHdll -# define DSFL1dll DSFL1dll -# define DSFL2dll DSFL2dll -# define ENTHALdll ENTHALdll -# define ENTROdll ENTROdll -# define ESFLSHdll ESFLSHdll -# define FGCTYdll FGCTYdll -# define FPVdll FPVdll -# define GERG04dll GERG04dll -# define GETFIJdll GETFIJdll -# define GETKTVdll GETKTVdll -# define GIBBSdll GIBBSdll -# define HSFLSHdll HSFLSHdll -# define INFOdll INFOdll -# define LIMITKdll LIMITKdll -# define LIMITSdll LIMITSdll -# define LIMITXdll LIMITXdll -# define MELTPdll MELTPdll -# define MELTTdll MELTTdll -# define MLTH2Odll MLTH2Odll -# define NAMEdll NAMEdll -# define PDFL1dll PDFL1dll -# define PDFLSHdll PDFLSHdll -# define PEFLSHdll PEFLSHdll -# define PHFL1dll PHFL1dll -# define PHFLSHdll PHFLSHdll -# define PQFLSHdll PQFLSHdll -# define PREOSdll PREOSdll -# define PRESSdll PRESSdll -# define PSFL1dll PSFL1dll -# define PSFLSHdll PSFLSHdll -# define PUREFLDdll PUREFLDdll -# define QMASSdll QMASSdll -# define QMOLEdll QMOLEdll -# define SATDdll SATDdll -# define SATEdll SATEdll -# define SATHdll SATHdll -# define SATPdll SATPdll -# define SATSdll SATSdll -# define SATTdll SATTdll -# define SETAGAdll SETAGAdll -# define SETKTVdll SETKTVdll -# define SETMIXdll SETMIXdll -# define SETMODdll SETMODdll -# define SETREFdll SETREFdll -# define SETUPdll SETUPdll -# define SPECGRdll SPECGRdll -# define SUBLPdll SUBLPdll -# define SUBLTdll SUBLTdll -# define SURFTdll SURFTdll -# define SURTENdll SURTENdll -# define TDFLSHdll TDFLSHdll -# define TEFLSHdll TEFLSHdll -# define THERM0dll THERM0dll -# define THERM2dll THERM2dll -# define THERM3dll THERM3dll -# define THERMdll THERMdll -# define THFLSHdll THFLSHdll -# define TPFLSHdll TPFLSHdll -# define TPFL2dll TPFL2dll -# define TPRHOdll TPRHOdll -# define TQFLSHdll TQFLSHdll -# define TRNPRPdll TRNPRPdll -# define TSFLSHdll TSFLSHdll -# define VIRBdll VIRBdll -# define VIRCdll VIRCdll -# define WMOLdll WMOLdll -# define XMASSdll XMASSdll -# define XMOLEdll XMOLEdll -#else // defined(WIN32) || defined(_WIN32) -// Define compiler specific calling conventions -// for the shared library. -# define LIBRARY_API -// Define function names for the shared library, -// in this case it is the librefprop.so and the -// names might change on some systems during -// the compilation of the Fortran files. -# ifdef _CRAY -# include -# define RPVersion RPVERSION -# define SETPATHdll SETPATHDLL -# define ABFL1dll ABFL1DLL -# define ABFL2dll ABFL2DLL -# define ACTVYdll ACTVYDLL -# define AGdll AGDLL -# define CCRITdll CCRITDLL -# define CP0dll CP0DLL -# define CRITPdll CRITPDLL -# define CSATKdll CSATKDLL -# define CV2PKdll CV2PKDLL -# define CVCPKdll CVCPKDLL -# define CVCPdll CVCPDLL -# define DBDTdll DBDTDLL -# define DBFL1dll DBFL1DLL -# define DBFL2dll DBFL2DLL -# define DDDPdll DDDPDLL -# define DDDTdll DDDTDLL -# define DEFLSHdll DEFLSHDLL -# define DHD1dll DHD1DLL -# define DHFL1dll DHFL1DLL -# define DHFL2dll DHFL2DLL -# define DHFLSHdll DHFLSHDLL -# define DIELECdll DIELECDLL -# define DOTFILLdll DOTFILLDLL -# define DPDD2dll DPDD2DLL -# define DPDDKdll DPDDKDLL -# define DPDDdll DPDDDLL -# define DPDTKdll DPDTKDLL -# define DPDTdll DPDTDLL -# define DPTSATKdll DPTSATKDLL -# define DSFLSHdll DSFLSHDLL -# define DSFL1dll DSFL1DLL -# define DSFL2dll DSFL2DLL -# define ENTHALdll ENTHALDLL -# define ENTROdll ENTRODLL -# define ESFLSHdll ESFLSHDLL -# define FGCTYdll FGCTYDLL -# define FPVdll FPVDLL -# define GERG04dll GERG04DLL -# define GETFIJdll GETFIJDLL -# define GETKTVdll GETKTVDLL -# define GIBBSdll GIBBSDLL -# define HSFLSHdll HSFLSHDLL -# define INFOdll INFODLL -# define LIMITKdll LIMITKDLL -# define LIMITSdll LIMITSDLL -# define LIMITXdll LIMITXDLL -# define MELTPdll MELTPDLL -# define MELTTdll MELTTDLL -# define MLTH2Odll MLTH2ODLL -# define NAMEdll NAMEDLL -# define PDFL1dll PDFL1DLL -# define PDFLSHdll PDFLSHDLL -# define PEFLSHdll PEFLSHDLL -# define PHFL1dll PHFL1DLL -# define PHFLSHdll PHFLSHDLL -# define PQFLSHdll PQFLSHDLL -# define PREOSdll PREOSDLL -# define PRESSdll PRESSDLL -# define PSFL1dll PSFL1DLL -# define PSFLSHdll PSFLSHDLL -# define PUREFLDdll PUREFLDDLL -# define QMASSdll QMASSDLL -# define QMOLEdll QMOLEDLL -# define SATDdll SATDDLL -# define SATEdll SATEDLL -# define SATHdll SATHDLL -# define SATPdll SATPDLL -# define SATSdll SATSDLL -# define SATTdll SATTDLL -# define SETAGAdll SETAGADLL -# define SETKTVdll SETKTVDLL -# define SETMIXdll SETMIXDLL -# define SETMODdll SETMODDLL -# define SETREFdll SETREFDLL -# define SETUPdll SETUPDLL -# define SPECGRdll SPECGRDLL -# define SUBLPdll SUBLPDLL -# define SUBLTdll SUBLTDLL -# define SURFTdll SURFTDLL -# define SURTENdll SURTENDLL -# define TDFLSHdll TDFLSHDLL -# define TEFLSHdll TEFLSHDLL -# define THERM0dll THERM0DLL -# define THERM2dll THERM2DLL -# define THERM3dll THERM3DLL -# define THERMdll THERMDLL -# define THFLSHdll THFLSHDLL -# define TPFLSHdll TPFLSHDLL -# define TPFL2dll TPFL2DLL -# define TPRHOdll TPRHODLL -# define TQFLSHdll TQFLSHDLL -# define TRNPRPdll TRNPRPDLL -# define TSFLSHdll TSFLSHDLL -# define VIRBdll VIRBDLL -# define VIRCdll VIRCDLL -# define WMOLdll WMOLDLL -# define XMASSdll XMASSDLL -# define XMOLEdll XMOLEDLL -# else // _CRAY not defined -# if !defined(_AIX) && !defined(__hpux) -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -# define SPECGRdll specgrdll_ -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -# endif // !defined(_AIX) && !defined(__hpux) -# endif // _CRAY not defined, else branch -#endif // defined(WIN32) || defined(_WIN32), else branch - - -// define new macros for function names -// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value -#define STR_VALUE(arg) #arg -#define FUNCTION_NAME(name) STR_VALUE(name) -//#define TEST_FUNC test_func -//#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) - -#define RPVersion_NAME FUNCTION_NAME(RPVersion) -#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) -#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) -#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) -#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) -#define AGdll_NAME FUNCTION_NAME(AGdll) -#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) -#define CP0dll_NAME FUNCTION_NAME(CP0dll) -#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) -#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) -#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) -#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) -#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) -#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) -#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) -#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) -#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) -#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) -#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) -#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) -#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) -#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) -#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) -#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) -#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) -#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) -#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) -#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) -#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) -#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) -#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) -#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) -#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) -#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) -#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) -#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) -#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) -#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) -#define FPVdll_NAME FUNCTION_NAME(FPVdll) -#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) -#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) -#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) -#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) -#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) -#define INFOdll_NAME FUNCTION_NAME(INFOdll) -#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) -#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) -#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) -#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) -#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) -#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) -#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) -#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) -#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) -#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) -#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) -#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) -#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) -#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) -#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) -#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) -#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) -#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) -#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) -#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) -#define SATDdll_NAME FUNCTION_NAME(SATDdll) -#define SATEdll_NAME FUNCTION_NAME(SATEdll) -#define SATHdll_NAME FUNCTION_NAME(SATHdll) -#define SATPdll_NAME FUNCTION_NAME(SATPdll) -#define SATSdll_NAME FUNCTION_NAME(SATSdll) -#define SATTdll_NAME FUNCTION_NAME(SATTdll) -#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) -#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) -#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) -#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) -#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) -#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) -#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) -#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) -#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) -#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) -#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) -#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) -#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) -#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) -#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) -#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) -#define THERMdll_NAME FUNCTION_NAME(THERMdll) -#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) -#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) -#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) -#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) -#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) -#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) -#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) -#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) -#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) -#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) -#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) -#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) - - -// I'll try to follow this example from: -// http://www.gershnik.com/tips/cpp.asp -////not a pointer but function type -//typedef void [compiler specific stuff] func_t(int, float); -// -////this is the function declaration -//func_t func; -// -////and this is the pointer type just for convenience -//typedef func_t * func_ptr; - -#ifdef __cplusplus -extern "C" { -#endif - // extra function for setup - typedef void (LIBRARY_API RPVersion_TYPE )( char* ); - typedef void (LIBRARY_API SETPATHdll_TYPE)( const char* ); - // - typedef void (LIBRARY_API ABFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ABFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ACTVYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API AGdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CCRITdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CP0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CRITPdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CV2PKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CVCPKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CVCPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DBFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DDDPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DDDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DHD1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DIELECdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DOTFILLdll_TYPE)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DPDD2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPTSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DSFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API ENTHALdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ENTROdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ESFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API FGCTYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); - typedef void (LIBRARY_API FPVdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API GERG04dll_TYPE)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API GETFIJdll_TYPE)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GIBBSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API HSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API INFOdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API LIMITKdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API LIMITSdll_TYPE)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); - typedef void (LIBRARY_API LIMITXdll_TYPE)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API MELTPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MELTTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MLTH2Odll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API NAMEdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API PDFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PREOSdll_TYPE)(INTEGER &); - typedef void (LIBRARY_API PRESSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API PSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PUREFLDdll_TYPE)(INTEGER &); - typedef void (LIBRARY_API QMASSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API QMOLEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETAGAdll_TYPE)(INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMIXdll_TYPE)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMODdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETREFdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - //typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*); - typedef void (LIBRARY_API SPECGRdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API SUBLPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SUBLTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURFTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURTENdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API THERM0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM3dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERMdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API TPRHOdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TRNPRPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API VIRBdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API VIRCdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API WMOLdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMASSdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMOLEdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - - //Declare the functions for direct access - RPVersion_TYPE RPVersion; - SETPATHdll_TYPE SETPATHdll; - ABFL1dll_TYPE ABFL1dll; - ABFL2dll_TYPE ABFL2dll; - ACTVYdll_TYPE ACTVYdll; - AGdll_TYPE AGdll; - CCRITdll_TYPE CCRITdll; - CP0dll_TYPE CP0dll; - CRITPdll_TYPE CRITPdll; - CSATKdll_TYPE CSATKdll; - CV2PKdll_TYPE CV2PKdll; - CVCPKdll_TYPE CVCPKdll; - CVCPdll_TYPE CVCPdll; - DBDTdll_TYPE DBDTdll; - DBFL1dll_TYPE DBFL1dll; - DBFL2dll_TYPE DBFL2dll; - DDDPdll_TYPE DDDPdll; - DDDTdll_TYPE DDDTdll; - DEFLSHdll_TYPE DEFLSHdll; - DHD1dll_TYPE DHD1dll; - DHFLSHdll_TYPE DHFLSHdll; - DHFL1dll_TYPE DHFL1dll; - DHFL2dll_TYPE DHFL2dll; - DIELECdll_TYPE DIELECdll; - DOTFILLdll_TYPE DOTFILLdll; - DPDD2dll_TYPE DPDD2dll; - DPDDKdll_TYPE DPDDKdll; - DPDDdll_TYPE DPDDdll; - DPDTKdll_TYPE DPDTKdll; - DPDTdll_TYPE DPDTdll; - DPTSATKdll_TYPE DPTSATKdll; - DSFLSHdll_TYPE DSFLSHdll; - DSFL1dll_TYPE DSFL1dll; - DSFL2dll_TYPE DSFL2dll; - ENTHALdll_TYPE ENTHALdll; - ENTROdll_TYPE ENTROdll; - ESFLSHdll_TYPE ESFLSHdll; - FGCTYdll_TYPE FGCTYdll; - FPVdll_TYPE FPVdll; - GERG04dll_TYPE GERG04dll; - GETFIJdll_TYPE GETFIJdll; - GETKTVdll_TYPE GETKTVdll; - GIBBSdll_TYPE GIBBSdll; - HSFLSHdll_TYPE HSFLSHdll; - INFOdll_TYPE INFOdll; - LIMITKdll_TYPE LIMITKdll; - LIMITSdll_TYPE LIMITSdll; - LIMITXdll_TYPE LIMITXdll; - MELTPdll_TYPE MELTPdll; - MELTTdll_TYPE MELTTdll; - MLTH2Odll_TYPE MLTH2Odll; - NAMEdll_TYPE NAMEdll; - PDFL1dll_TYPE PDFL1dll; - PDFLSHdll_TYPE PDFLSHdll; - PEFLSHdll_TYPE PEFLSHdll; - PHFL1dll_TYPE PHFL1dll; - PHFLSHdll_TYPE PHFLSHdll; - PQFLSHdll_TYPE PQFLSHdll; - PREOSdll_TYPE PREOSdll; - PRESSdll_TYPE PRESSdll; - PSFL1dll_TYPE PSFL1dll; - PSFLSHdll_TYPE PSFLSHdll; - PUREFLDdll_TYPE PUREFLDdll; - QMASSdll_TYPE QMASSdll; - QMOLEdll_TYPE QMOLEdll; - SATDdll_TYPE SATDdll; - SATEdll_TYPE SATEdll; - SATHdll_TYPE SATHdll; - SATPdll_TYPE SATPdll; - SATSdll_TYPE SATSdll; - SATTdll_TYPE SATTdll; - SETAGAdll_TYPE SETAGAdll; - SETKTVdll_TYPE SETKTVdll; - SETMIXdll_TYPE SETMIXdll; - SETMODdll_TYPE SETMODdll; - SETREFdll_TYPE SETREFdll; - SETUPdll_TYPE SETUPdll; - SPECGRdll_TYPE SPECGRdll; - SUBLPdll_TYPE SUBLPdll; - SUBLTdll_TYPE SUBLTdll; - SURFTdll_TYPE SURFTdll; - SURTENdll_TYPE SURTENdll; - TDFLSHdll_TYPE TDFLSHdll; - TEFLSHdll_TYPE TEFLSHdll; - THERM0dll_TYPE THERM0dll; - THERM2dll_TYPE THERM2dll; - THERM3dll_TYPE THERM3dll; - THERMdll_TYPE THERMdll; - THFLSHdll_TYPE THFLSHdll; - TPFLSHdll_TYPE TPFLSHdll; - TPFL2dll_TYPE TPFL2dll; - TPRHOdll_TYPE TPRHOdll; - TQFLSHdll_TYPE TQFLSHdll; - TRNPRPdll_TYPE TRNPRPdll; - TSFLSHdll_TYPE TSFLSHdll; - VIRBdll_TYPE VIRBdll; - VIRCdll_TYPE VIRCdll; - WMOLdll_TYPE WMOLdll; - XMASSdll_TYPE XMASSdll; - XMOLEdll_TYPE XMOLEdll; - - //Define explicit function pointers - typedef RPVersion_TYPE * RPVersion_POINTER; - typedef SETPATHdll_TYPE * SETPATHdll_POINTER; - typedef ABFL1dll_TYPE * ABFL1dll_POINTER; - typedef ABFL2dll_TYPE * ABFL2dll_POINTER; - typedef ACTVYdll_TYPE * ACTVYdll_POINTER; - typedef AGdll_TYPE * AGdll_POINTER; - typedef CCRITdll_TYPE * CCRITdll_POINTER; - typedef CP0dll_TYPE * CP0dll_POINTER; - typedef CRITPdll_TYPE * CRITPdll_POINTER; - typedef CSATKdll_TYPE * CSATKdll_POINTER; - typedef CV2PKdll_TYPE * CV2PKdll_POINTER; - typedef CVCPKdll_TYPE * CVCPKdll_POINTER; - typedef CVCPdll_TYPE * CVCPdll_POINTER; - typedef DBDTdll_TYPE * DBDTdll_POINTER; - typedef DBFL1dll_TYPE * DBFL1dll_POINTER; - typedef DBFL2dll_TYPE * DBFL2dll_POINTER; - typedef DDDPdll_TYPE * DDDPdll_POINTER; - typedef DDDTdll_TYPE * DDDTdll_POINTER; - typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; - typedef DHD1dll_TYPE * DHD1dll_POINTER; - typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; - typedef DHFL1dll_TYPE * DHFL1dll_POINTER; - typedef DHFL2dll_TYPE * DHFL2dll_POINTER; - typedef DIELECdll_TYPE * DIELECdll_POINTER; - typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; - typedef DPDD2dll_TYPE * DPDD2dll_POINTER; - typedef DPDDKdll_TYPE * DPDDKdll_POINTER; - typedef DPDDdll_TYPE * DPDDdll_POINTER; - typedef DPDTKdll_TYPE * DPDTKdll_POINTER; - typedef DPDTdll_TYPE * DPDTdll_POINTER; - typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; - typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; - typedef DSFL1dll_TYPE * DSFL1dll_POINTER; - typedef DSFL2dll_TYPE * DSFL2dll_POINTER; - typedef ENTHALdll_TYPE * ENTHALdll_POINTER; - typedef ENTROdll_TYPE * ENTROdll_POINTER; - typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; - typedef FGCTYdll_TYPE * FGCTYdll_POINTER; - typedef FPVdll_TYPE * FPVdll_POINTER; - typedef GERG04dll_TYPE * GERG04dll_POINTER; - typedef GETFIJdll_TYPE * GETFIJdll_POINTER; - typedef GETKTVdll_TYPE * GETKTVdll_POINTER; - typedef GIBBSdll_TYPE * GIBBSdll_POINTER; - typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; - typedef INFOdll_TYPE * INFOdll_POINTER; - typedef LIMITKdll_TYPE * LIMITKdll_POINTER; - typedef LIMITSdll_TYPE * LIMITSdll_POINTER; - typedef LIMITXdll_TYPE * LIMITXdll_POINTER; - typedef MELTPdll_TYPE * MELTPdll_POINTER; - typedef MELTTdll_TYPE * MELTTdll_POINTER; - typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; - typedef NAMEdll_TYPE * NAMEdll_POINTER; - typedef PDFL1dll_TYPE * PDFL1dll_POINTER; - typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; - typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; - typedef PHFL1dll_TYPE * PHFL1dll_POINTER; - typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; - typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; - typedef PREOSdll_TYPE * PREOSdll_POINTER; - typedef PRESSdll_TYPE * PRESSdll_POINTER; - typedef PSFL1dll_TYPE * PSFL1dll_POINTER; - typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; - typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; - typedef QMASSdll_TYPE * QMASSdll_POINTER; - typedef QMOLEdll_TYPE * QMOLEdll_POINTER; - typedef SATDdll_TYPE * SATDdll_POINTER; - typedef SATEdll_TYPE * SATEdll_POINTER; - typedef SATHdll_TYPE * SATHdll_POINTER; - typedef SATPdll_TYPE * SATPdll_POINTER; - typedef SATSdll_TYPE * SATSdll_POINTER; - typedef SATTdll_TYPE * SATTdll_POINTER; - typedef SETAGAdll_TYPE * SETAGAdll_POINTER; - typedef SETKTVdll_TYPE * SETKTVdll_POINTER; - typedef SETMIXdll_TYPE * SETMIXdll_POINTER; - typedef SETMODdll_TYPE * SETMODdll_POINTER; - typedef SETREFdll_TYPE * SETREFdll_POINTER; - typedef SETUPdll_TYPE * SETUPdll_POINTER; - typedef SPECGRdll_TYPE * SPECGRdll_POINTER; - typedef SUBLPdll_TYPE * SUBLPdll_POINTER; - typedef SUBLTdll_TYPE * SUBLTdll_POINTER; - typedef SURFTdll_TYPE * SURFTdll_POINTER; - typedef SURTENdll_TYPE * SURTENdll_POINTER; - typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; - typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; - typedef THERM0dll_TYPE * THERM0dll_POINTER; - typedef THERM2dll_TYPE * THERM2dll_POINTER; - typedef THERM3dll_TYPE * THERM3dll_POINTER; - typedef THERMdll_TYPE * THERMdll_POINTER; - typedef THFLSHdll_TYPE * THFLSHdll_POINTER; - typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; - typedef TPFL2dll_TYPE * TPFL2dll_POINTER; - typedef TPRHOdll_TYPE * TPRHOdll_POINTER; - typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; - typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; - typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; - typedef VIRBdll_TYPE * VIRBdll_POINTER; - typedef VIRCdll_TYPE * VIRCdll_POINTER; - typedef WMOLdll_TYPE * WMOLdll_POINTER; - typedef XMASSdll_TYPE * XMASSdll_POINTER; - typedef XMOLEdll_TYPE * XMOLEdll_POINTER; - -#ifdef __cplusplus -} // extern "C" -#endif -// REFPROP_H -#endif - diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.h b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h similarity index 100% rename from _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.h rename to _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.org.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp similarity index 100% rename from _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.org.cpp rename to _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp similarity index 100% rename from _REFPROP-Wrapper/Version 0.5_linux/refprop_wrapper.poco.cpp rename to _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp diff --git a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp similarity index 96% rename from _REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp rename to _REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp index 9fb00fc..65b0501 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp @@ -21,7 +21,7 @@ int main(int argc, char* argv[]){ if (argc<5){ // printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); - printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/home/jowr/Documents/Fluids/refprop/v9.0/\" .1\n"); + printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/home/jowr/Documents/Fluids/Refprop/v9.0/\" .1\n"); return 1; } diff --git a/readme.md b/readme.md index 3e833ac..7bdb6da 100644 --- a/readme.md +++ b/readme.md @@ -2,8 +2,6 @@ #Welcome to REFPROP2Modelica! This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the "Media" framework inside Modelica. It has only been tested with Dymola sofar. -Please be aware that you might need a copy of the Poco C++ framework to compile the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. - ## Installation Instructions ### Windows @@ -12,16 +10,18 @@ For Windows, please follow these instructions 1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". 2. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.LIB to %DYMOLADIR%\\BIN\\LIB\ (%DYMOLADIR% is DYMOLA's program directory) 3. Copy \_REFPROP-Wrapper\Version x.x\REFPROP_WRAPPER.H to %DYMOLADIR%\\SOURCE\\ -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\"; ### Linux For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. 1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". 2. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. -3. Call "make libheader library" and "sudo make installlib" to compile and install refprop. -4. Call "make wrapheader wrapper" and "sudo make installwrap" as well as "sudo make fixit" to compile and install the wrapper. -5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; +3. Make sure to have the shared library "librefprop.so" available. You might want to check https://github.com/jowr/librefprop.so for details. +4. Call "make all" and "sudo make install" as well as "sudo make fixit" to compile and install the wrapper library. +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; + +To remove the files from your system, please use "sudo make uninstall". Please be aware that you might need a copy of the Poco C++ framework to compile future versions the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. \ No newline at end of file From d948b64be4d50476907d60d20ea288009efd6b9c Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 31 Oct 2012 06:21:34 -0700 Subject: [PATCH 10/57] 2012:10:31 14:20 - Now using the poco framework in the standard version, remember to have all dependencies when compiling. --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 4 +- .../src/refprop_wrapper.poco.cpp | 716 +++++++++++------- .../src/refpropwrappertest.cpp | 19 +- 3 files changed, 458 insertions(+), 281 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index 4e02c08..657396a 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -103,7 +103,7 @@ $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION): $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENS .PHONY : library library : $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) -$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): nopoco +$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): poco .PHONY : nopoco nopoco : $(SRCDIR)/$(LIBFILE).org.o @@ -111,7 +111,7 @@ nopoco : $(SRCDIR)/$(LIBFILE).org.o .PHONY : poco poco : $(SRCDIR)/$(LIBFILE).poco.o - $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).poco.o $(LIBS) -lPocoFoundation + $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).poco.o -lPocoFoundation ########################################################### # Compile the wrapper class tests. diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp index d0ce770..1a624b2 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp @@ -18,7 +18,7 @@ DTU Mechanical Engineering needs - librefprop.h - header for librefprop.so, based on examples + refprop_lib.h - header for librefprop.so, based on examples refprop_wrapper.h - header for static REFPROP_wrapper.a, also needed by Dymola Use the provided makefile to install the library file from source. @@ -29,14 +29,14 @@ #include #if defined(WIN32) || defined(_WIN32) # include -# include "REFPROP_dll.h" +//# include "REFPROP_dll.h" #else // assuming Linux system # include # include -# include //# include // dlopen etc # include // tolower etc #endif +#include //# error "Could not determine system." #include "refprop_wrapper.h" @@ -47,6 +47,8 @@ #include "Poco/Environment.h" #include "Poco/StringTokenizer.h" #include "Poco/String.h" +#include "Poco/Exception.h" + // Some constants... const long filepathlength=1024; @@ -55,111 +57,71 @@ const long lengthofreference=3; const long refpropcharlength=255; const long ncmax=20; // Note: ncmax is the max number of components -//Poco::SharedLibrary RefpropdllInstance; +Poco::SharedLibrary *RefpropdllInstance = NULL; char loadedfluids[refpropcharlength]; char loadedpath[filepathlength]; -//// Define the functions either by their pointers or type. -//WMOLdll_POINTER WMOLdll; -//TPFL2dll_POINTER TPFL2dll; -//TPFLSHdll_POINTER TPFLSHdll; -//PHFL1dll_POINTER PHFL1dll; -//PHFLSHdll_POINTER PHFLSHdll; -//PDFL1dll_POINTER PDFL1dll; -//PDFLSHdll_POINTER PDFLSHdll; -//PSFLSHdll_POINTER PSFLSHdll; -//PQFLSHdll_POINTER PQFLSHdll; -//THFLSHdll_POINTER THFLSHdll; -//TDFLSHdll_POINTER TDFLSHdll; -//TSFLSHdll_POINTER TSFLSHdll; -//TQFLSHdll_POINTER TQFLSHdll; -//DHFL1dll_POINTER DHFL1dll; -//DHFL2dll_POINTER DHFL2dll; -//DHFLSHdll_POINTER DHFLSHdll; -//HSFLSHdll_POINTER HSFLSHdll; -//DSFL1dll_POINTER DSFL1dll; -//DSFL2dll_POINTER DSFL2dll; -//DSFLSHdll_POINTER DSFLSHdll; -//TRNPRPdll_POINTER TRNPRPdll; -//SATTdll_POINTER SATTdll; -//SATPdll_POINTER SATPdll; -//SATDdll_POINTER SATDdll; +// Define the functions either by their pointers or type. +WMOLdll_POINTER WMOL = NULL; +TPFL2dll_POINTER TPFL2 = NULL; +TPFLSHdll_POINTER TPFLSH = NULL; +PHFL1dll_POINTER PHFL1 = NULL; +PHFLSHdll_POINTER PHFLSH = NULL; +PDFL1dll_POINTER PDFL1 = NULL; +PDFLSHdll_POINTER PDFLSH = NULL; +PSFLSHdll_POINTER PSFLSH = NULL; +PQFLSHdll_POINTER PQFLSH = NULL; +THFLSHdll_POINTER THFLSH = NULL; +TDFLSHdll_POINTER TDFLSH = NULL; +TSFLSHdll_POINTER TSFLSH = NULL; +TQFLSHdll_POINTER TQFLSH = NULL; +DHFL1dll_POINTER DHFL1 = NULL; +DHFL2dll_POINTER DHFL2 = NULL; +DHFLSHdll_POINTER DHFLSH = NULL; +HSFLSHdll_POINTER HSFLSH = NULL; +DSFL1dll_POINTER DSFL1 = NULL; +DSFL2dll_POINTER DSFL2 = NULL; +DSFLSHdll_POINTER DSFLSH = NULL; +TRNPRPdll_POINTER TRNPRP = NULL; +SATTdll_POINTER SATT = NULL; +SATPdll_POINTER SATP = NULL; +SATDdll_POINTER SATD = NULL; + //str_replace (fluidnames, "|", replace, nX) -char *str_replace(char *str, char *search, char *replace, long *count) { - int i,n_ret; - int newlen = strlen(replace); - int oldlen = strlen(search); - char *ret; +char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { + *count = 0; + char ret[filepathlength]; + + std::string fluids(str); + std::string dlimit(search); + std::string substi(replace); + std::string result; + + // if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); + // if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); + // if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); + // if (DEBUGMODE) printf("nX: %li\n\n",*count); + + Poco::StringTokenizer tokens(fluids.c_str(), dlimit.c_str(), Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); + result = std::string(Poco::cat(substi, tokens.begin(), tokens.end())); + + strcpy(ret,result.c_str()); + //strcat(ret,'\0'); + + *count = tokens.count()-1; + + if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); + if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); + if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); + if (DEBUGMODE) printf("replaced: %s\n",result.c_str()); + if (DEBUGMODE) printf("nX: %li\n\n",*count); + +return ret; - //count occurrences of searchstring - for (i = 0; oldlen && str[i]; ++i) - if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr - ++*count, i+=oldlen - 1; - } - ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); -// std::string stri (&str); -// std::string sear (&search); -// Poco::StringTokenizer StrTok(stri,sear,Poco::StringTokenizer::TOK_TRIM); -// *count = StrTok.count(); -// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); - - if (!ret){ - printf("Could not allocate memory"); - return ""; - } - - if (!*count){ - strncpy(ret,str,n_ret); - //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); - }else{ - i = 0; - while (*str) - if (strstr(str, search) == str) - strncpy(&ret[i], replace,n_ret-i-1), - i += newlen, - str += oldlen; - else - ret[i++] = *str++; - ret[i] = '\0'; - } - return ret; } -//char *str_replace(char *str, char *search, char *replace, long *count) { -// int i,n_ret; -// int newlen = strlen(replace); -// int oldlen = strlen(search); -// char *ret; -// *count = 0; -// -// //count occurrences of searchstring -// for (i = 0; oldlen && str[i]; ++i) -// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr -// ++*count, i+=oldlen - 1; -// } -// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); -// if (!ret){ -// printf("Could not allocate memory"); -// return ""; -// } -// -// if (!*count){ -// strncpy(ret,str,n_ret); -// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); -// }else{ -// i = 0; -// while (*str) -// if (strstr(str, search) == str) -// strncpy(&ret[i], replace,n_ret-i-1), -// i += newlen, -// str += oldlen; -// else -// ret[i++] = *str++; -// ret[i] = '\0'; -// } -// return ret; -//} + int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ // Sets up the interface to the REFPROP.DLL @@ -167,10 +129,10 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr // char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; long ierr=0; -// DEBUGMODE = 1; +// DEBUGMODE = 1; if (strlen(REFPROP_PATH_CHAR)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %i)\n",strlen(REFPROP_PATH_CHAR),filepathlength); + sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %li)\n",strlen(REFPROP_PATH_CHAR),filepathlength); return 0; } // Define temporary objects for checks. @@ -180,7 +142,7 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr Poco::Path FLD_PATH(true); char LIBRARY_CHAR[filepathlength]; Poco::Path LIB_PATH(true); - Poco::File theFile; + //Poco::File theFile; // Parse the string and append a path separator if necessary. REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); @@ -190,116 +152,170 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr // Check the path if running in debugmode if (DEBUGMODE) { - theFile = Poco::File(REF_PATH); - if ( !theFile.isDirectory() || !theFile.canRead() ){ - sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - return 0; + Poco::File refFile(REF_PATH); + if ( !refFile.isDirectory() || !refFile.canRead() ){ + printf ("REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + return 0; + } else { + printf ("REF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); } } // The fluid files are in the Refprop directory, append "fluids". FLD_PATH.parse(REF_PATH_CHAR); FLD_PATH.pushDirectory(FLUIDS_CHAR); - - if (DEBUGMODE) { - // Determine which library file should be loaded - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - strcpy(LIBRARY_CHAR,"librefprop.so"); - } else { - strcpy(LIBRARY_CHAR,"refprop.dll"); - } - std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... - //std::string path(Poco::Environment::get("PATH")); - bool found_lib = Poco::Path::find(path, LIBRARY_CHAR, LIB_PATH); - if (found_lib) { - printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); - } else { - printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); - } - } else { - LIB_PATH.parse(REF_PATH_CHAR); + +// //std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... +// Poco::Path SRC_PATH; +// SRC_PATH.parse(Poco::Environment::get("PATH")); + +// if (DEBUGMODE) { +// // Determine which library file should be loaded +// bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); +// if (is_linux){ +// strcpy(LIBRARY_CHAR,"librefprop.so"); +// SRC_PATH.pushDirectory("/usr/local/lib"); +// } else { +// strcpy(LIBRARY_CHAR,"refprop.dll"); +// SRC_PATH.pushDirectory(REF_PATH.toString()); +// } + + + //bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); +// if (found_lib) { +// printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); +// } else { +// printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); +// } +// } else { +// LIB_PATH.parse(REF_PATH_CHAR); +// } + + //LIB_PATH.parse(LIBRARY_CHAR); + +// if (DEBUGMODE) { +// printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); +// printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); +// printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); +// printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); +// } + + Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... + + if (RefpropdllInstance==NULL) { // we need to load the library + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); + + // Check the OS and assign the right names for the library + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + strcpy(LIBRARY_CHAR,"librefprop.so"); + SRC_PATH.parse("/usr/local/lib"); + } else { + strcpy(LIBRARY_CHAR,"refprop.dll"); + SRC_PATH = REF_PATH; + } + + // search the library at the given path + bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); + if (found_lib) { + if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + } else { + if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + return 0; + } + + // check if the file is correct and executable + if (DEBUGMODE) { + Poco::File libFile(LIB_PATH); + if ( !libFile.isFile() || !libFile.canRead() ){ + printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + sprintf (errormsg,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + return 0; + } else { + printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); + } + } + + // load a new library instance + RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); + + } else { // library was already loaded + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); } - - // Check for new fluids and if the library has to be loaded again. - if (DEBUGMODE) printf ("Comparison of fluids : %i \n", strcmp(fluidnames,loadedfluids) ); - if (DEBUGMODE) printf ("Comparison of path : %i \n", strcmp(REF_PATH_CHAR,loadedpath) ); - if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); - -// if (strcmp(fluidnames,loadedfluids)==0) { -// if ( strcmp(REF_PATH_CHAR,loadedpath)==0 ) { -// sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); -// if (DEBUGMODE) printf ("No setup needed: %s and %s \n", REF_PATH_CHAR,loadedpath ); -// return 0; -// } -// } - - strcpy(loadedpath,REF_PATH_CHAR); - + + // Now the library is loaded and we can start checkicng the fluid path + if (DEBUGMODE) { + Poco::File fldFile(FLD_PATH); + if ( !fldFile.isDirectory() || !fldFile.canRead() ){ + printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + return 0; + } else { + printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); + } + } + char FLD_PATH_CHAR[filepathlength]; + strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + + if (DEBUGMODE) { + printf ("%s\n"," "); printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); - printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); + printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); + printf ("%s\n"," "); } - if (DEBUGMODE) { - theFile = Poco::File(LIB_PATH); - if ( !theFile.isFile() || !theFile.canExecute() ){ - sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); - return 0; - } - } - char LIB_PATH_CHAR[filepathlength]; - strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); - - if (DEBUGMODE) { - theFile = Poco::File(FLD_PATH); - if ( !theFile.isDirectory() || !theFile.canRead() ){ - sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return 0; - } - } - char FLD_PATH_CHAR[filepathlength]; - strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - -//// First we load the library with the POCO foundation -//// classes and then define all the needed functions -//// by their names and a cast to the correct type. -// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); -// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); -// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); -// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { -// RefpropdllInstance.unload(); -// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); -// RefpropdllInstance.load(LIB_PATH_CHAR); -// } -// -// if (!RefpropdllInstance.isLoaded()){ -// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); -// return 100; -// } + // Check for new fluids and if the library has to be loaded again. + bool isFluid = (strcmp(fluidnames,loadedfluids)==0); + bool isPath = (strcmp(REF_PATH_CHAR,loadedpath)==0); + if (DEBUGMODE) printf ("Comparison of fluids : %i \n", isFluid ); + if (DEBUGMODE) printf ("Comparison of path : %i \n\n", isPath ); + //if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; char *hf; + +// // // // if (isFluid && isPath) { +// // // // //sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); +// // // // if (DEBUGMODE) printf ("No setup needed, fluids (%s) and path (%s) did not change.\n\n", fluidnames,REF_PATH_CHAR); +// // // // // // // // return 0; +// // // // } else { + // we need to call setup + + char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; +// // // // char *hf; //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".FLD|"); + char replace[filepathlength+6]; + strcpy(replace,".FLD|"); //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); + strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; hf = (char*) calloc(hf_len, sizeof(char)); strncpy(hf,FLD_PATH_CHAR,hf_len); - strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... + + char replaced[filepathlength]; + + strcpy(replaced,str_replace(fluidnames, "|", replace, nX, DEBUGMODE)); + + //str_replace returns the number of delimiters -> nX, but components are one more ... if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %i)\n",ncmax); + sprintf(errormsg,"Too many components (More than %li)\n",ncmax); return 0; } + + + strncat(hf,replaced,hf_len-strlen(hf)); + strncat(hf,".FLD",hf_len-strlen(hf)); + if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path @@ -307,39 +323,15 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr strcpy(hrf,"DEF"); -// SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); - if (DEBUGMODE) printf("Running SETUPdll...\n"); - SETUPdll(*nX, hf, hfmix, hrf, ierr, herr); + SETUPdll_POINTER SETUP = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); + if (DEBUGMODE) printf("Running SETUP...\n"); + SETUP(*nX, hf, hfmix, hrf, ierr, herr); + strcpy(loadedfluids,fluidnames); - if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); - -// WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); -// TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); -// TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); -// PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); -// PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); -// PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); -// PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); -// PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); -// PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); -// THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); -// TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); -// TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); -// TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); -// DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); -// DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); -// DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); -// HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); -// DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); -// DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); -// DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); -// TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); -// SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); -// SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); -// SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); - - -// if (DEBUGMODE) printf("Error code processing...\n"); + strcpy(loadedpath,REF_PATH_CHAR); + if (DEBUGMODE) printf("SETUP run complete (Error no: %li)\n",ierr); + + if (DEBUGMODE) printf("Error code processing...\n"); switch(ierr){ case 101: //strcpy(errormsg,"error in opening file"); @@ -354,7 +346,7 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr // if (DEBUGMODE) printf("Error -103\n"); strcpy(errormsg,"unknown model encountered in file"); break; - case 104: + case 104: // if (DEBUGMODE) printf("Error 104\n"); strcpy(errormsg,"error in setup of model"); break; @@ -383,8 +375,152 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr strncpy(errormsg,herr,errormessagelength); break; } - free(hf); +// // // // free(hf); return ierr; + + +// if (DEBUGMODE) { +// theFile = Poco::File(LIB_PATH); +// if ( !theFile.isFile() || !theFile.canExecute() ){ +// sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); +// return 0; +// } +// } +// char LIB_PATH_CHAR[filepathlength]; +// strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); +// +// if (DEBUGMODE) { +// theFile = Poco::File(FLD_PATH); +// if ( !theFile.isDirectory() || !theFile.canRead() ){ +// sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); +// return 0; +// } +// } +// char FLD_PATH_CHAR[filepathlength]; +// strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + +//// First we load the library with the POCO foundation +//// classes and then define all the needed functions +//// by their names and a cast to the correct type. +// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); +// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); +// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); +// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { +// RefpropdllInstance.unload(); +// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); +// RefpropdllInstance.load(LIB_PATH_CHAR); +// } +// +// if (!RefpropdllInstance.isLoaded()){ +// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); +// return 100; +// } + + +// char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; +// char *hf; +// +// //parse fluid composition string and insert absolute paths +// char replace[filepathlength+6]; +// strcpy(replace,".FLD|"); +// //if (DEBUGMODE) printf("REPLACE: %s\n",replace); +// strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); +// +// int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; +// hf = (char*) calloc(hf_len, sizeof(char)); +// +// strncpy(hf,FLD_PATH_CHAR,hf_len); +// strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... +// if (++*nX>ncmax){ //...that's why nX is incremented +// sprintf(errormsg,"Too many components (More than %i)\n",ncmax); +// return 0; +// } +// strncat(hf,".FLD",hf_len-strlen(hf)); +// if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); +// +// strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path +// strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); +// strcpy(hrf,"DEF"); +// +// +// // SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); +// if (DEBUGMODE) printf("Running SETUPdll...\n"); +// SETUP(*nX, hf, hfmix, hrf, ierr, herr); +// strcpy(loadedfluids,fluidnames); +// if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); +// +// // WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); +// // TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); +// // TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); +// // PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); +// // PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); +// // PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); +// // PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); +// // PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); +// // PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); +// // THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); +// // TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); +// // TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); +// // TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); +// // DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); +// // DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); +// // DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); +// // HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); +// // DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); +// // DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); +// // DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); +// // TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); +// // SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); +// // SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); +// // SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); + + +// // if (DEBUGMODE) printf("Error code processing...\n"); +// switch(ierr){ +// case 101: +// //strcpy(errormsg,"error in opening file"); +// // if (DEBUGMODE) printf("Error 101\n"); +// sprintf(errormsg,"error in opening file %s",hf); +// break; +// case 102: +// // if (DEBUGMODE) printf("Error 102\n"); +// strcpy(errormsg,"error in file or premature end of file"); +// break; +// case -103: +// // if (DEBUGMODE) printf("Error -103\n"); +// strcpy(errormsg,"unknown model encountered in file"); +// break; +// case 104: +// // if (DEBUGMODE) printf("Error 104\n"); +// strcpy(errormsg,"error in setup of model"); +// break; +// case 105: +// // if (DEBUGMODE) printf("Error 105\n"); +// strcpy(errormsg,"specified model not found"); +// break; +// case 111: +// // if (DEBUGMODE) printf("Error 111\n"); +// strcpy(errormsg,"error in opening mixture file"); +// break; +// case 112: +// // if (DEBUGMODE) printf("Error 112\n"); +// strcpy(errormsg,"mixture file of wrong type"); +// break; +// case 114: +// // if (DEBUGMODE) printf("Error 114\n"); +// strcpy(errormsg,"nc<>nc from setmod"); +// break; +// case 0: +// break; +// default: +// // if (DEBUGMODE) printf("Unknown error\n"); +// strcpy(errormsg,"Unknown error"); +// //strcpy(errormsg,"Setup was successful!"); +// strncpy(errormsg,herr,errormessagelength); +// break; +// } +// free(hf); +// return ierr; } @@ -395,12 +531,12 @@ double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *p statevars: string of any combination of two variables out of p,T,h,s,d fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll OUTPUT return value: value of variable specified by the input variable what props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message + errormsg: string containing error message */ char statevars[3]; double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; @@ -424,9 +560,10 @@ OUTPUT } //CALCULATE MOLAR MASS -// WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); -// WMOLdll_TYPE * WMOLdll = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); - WMOLdll(x,wm); +// WMOL = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); +// WMOLdll_TYPE * WMOL = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); + WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); + WMOL(x,wm); // sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); wm /= 1000; //g/mol -> kg/mol @@ -470,113 +607,132 @@ OUTPUT } /* -//...If phase j is known, call TPRHOdll: +//...If phase j is known, call TPRHO: long j=2; //phase definition(j=1: Liquid, j=2: Vapor) long tmp_int=0; TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); + TPRHO(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); */ //...If phase is not known, call TPFLSH double xliq[ncmax],xvap[ncmax],f[ncmax]; long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ + kq--flag specifying units for input quality + kq = 1 quality on MOLAR basis [moles vapor/total moles] + kq = 2 quality on MASS basis [mass vapor/total mass]*/ // sprintf(errormsg,"Huhu! %s %d", statevars, ierr); if (ierr==0){ if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ // strcat(errormsg,"Bin in TP!"); if (phase==2){ //fluid state is known to be two phase // TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + TPFL2 = (TPFL2dll_POINTER) RefpropdllInstance->getSymbol(TPFL2dll_NAME); + TPFL2(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); }else{ // TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + TPFLSH = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); + TPFLSH(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); } }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ // if (phase==1){ //fluid state is known to be single phase //// PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); -// PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +// PHFL1 = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); +// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); //// if (liqvap==1) dl=d; else dv=d; // }else{ //// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + PHFLSH = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); + PHFLSH(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); // } }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ if (phase==1){ //fluid state is known to be single phase // PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); + PDFL1 = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); + PDFL1(p,d,x,T,ierr,herr,errormessagelength); }else{ // PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + PDFLSH = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); + PDFLSH(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); } }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ /* if (phase==1){ //fluid state is known to be single phase PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); + PSFL1(p,s,x,kph,T,d,ierr,herr,errormessagelength); if (liqvap==1) dl=d; else dv=d; }else{*/ // PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + PSFLSH = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); + PSFLSH(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); // } }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ // PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + PQFLSH = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); + PQFLSH(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); // strcat(errormsg,"Bin in PQ!"); }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ /* if (phase==1){ //fluid state is known to be single phase THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); + THFL1(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); }else{*/ // THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); + THFLSH = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); long kr = 2; /* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + THFLSH (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); // } }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ // TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + TDFLSH = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); + TDFLSH(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ // TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); + TSFLSH = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); long kr = 2; - TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + TSFLSH(T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ // TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + TQFLSH = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); + TQFLSH(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ switch(phase){ //fluid state is known to be single phase case 1: // DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); + DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); + DHFL1(d,h,x,T,ierr,herr,errormessagelength); break; case 2: // DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + DHFL2 = (DHFL2dll_POINTER) RefpropdllInstance->getSymbol(DHFL2dll_NAME); + DHFL2(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); break; default: // DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + DHFLSH = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); + DHFLSH(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); break; } }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ // HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); + HSFLSH = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); + HSFLSH(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ switch(phase){ //fluid state is known to be single phase case 1: // DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); + DSFL1 = (DSFL1dll_POINTER) RefpropdllInstance->getSymbol(DSFL1dll_NAME); + DSFL1(d,s,x,T,ierr,herr,errormessagelength); break; case 2: // DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + DSFL2 = (DSFL2dll_POINTER) RefpropdllInstance->getSymbol(DSFL2dll_NAME); + DSFL2(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); break; default: // DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + DSFLSH = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); + DSFLSH(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); break; } }else @@ -587,7 +743,8 @@ OUTPUT case 'v': //dynamic viscosity uPa.s case 'l': //thermal conductivity W/m.K // TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); + TRNPRP = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); + TRNPRP(T,d,x,eta,tcx,ierr,herr,errormessagelength); break; } @@ -596,7 +753,7 @@ OUTPUT case 1: sprintf(errormsg,"T=%f < Tmin",T); break; - case 4: + case 4: sprintf(errormsg,"P=%f < 0",p); break; case 5: @@ -611,10 +768,10 @@ OUTPUT case 12: sprintf(errormsg,"x out of range and P=%f < 0",p); break; - case 13: + case 13: sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); break; - case 16: + case 16: strcpy(errormsg,"TPFLSH error: p>melting pressure"); break; case -31: @@ -686,9 +843,9 @@ OUTPUT //CONVERT TO SI-UNITS if (ierr==0){ - WMOLdll(xliq,wmliq); + WMOL(xliq,wmliq); wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); + WMOL(xvap,wmvap); wmvap /= 1000; //g/mol -> kg/mol //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); d *= wm*1000; //mol/dm� -> kg/m� @@ -767,12 +924,12 @@ double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double statevar: string of 1 variable out of p,T,h,s,d fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory statevarval: values of the variable specified in statevar - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll OUTPUT return value: value of variable specified by the input variable what props: Array containing all calculated values - errormsg: string containing error message + errormsg: string containing error message */ double p, T, d, val, dl,dv,wm,wmliq,wmvap; long nX,ierr=0; @@ -787,7 +944,7 @@ OUTPUT //initialize interface to REFPROP.dll if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ - printf("Error no. %i initializing REFPROP: \"%s\"\n", props[0], errormsg); + printf("Error no. %f initializing REFPROP: \"%s\"\n", props[0], errormsg); return 0; } @@ -795,15 +952,16 @@ OUTPUT //CALCULATE MOLAR MASS // WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); - WMOLdll(x,wm); + WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); + WMOL(x,wm); // sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); wm /= 1000; //g/mol -> kg/mol - if (DEBUGMODE) printf("\nwm converted.\n"); + if (DEBUGMODE) printf("wm converted.\n"); - if (DEBUGMODE) printf("\statevar is %s \n",statevar_in); + if (DEBUGMODE) printf("statevar is %s \n",statevar_in); //identify and assign passed state variables // char tmpstr[1]; // strcpy(tmpstr,statevar[0]); @@ -834,7 +992,7 @@ OUTPUT break; */ default: props[0] = 2; - sprintf(errormsg,"Unknown state variable: %c", statevarval); + sprintf(errormsg,"Unknown state variable: %f", statevarval); return 0; } } @@ -845,17 +1003,19 @@ OUTPUT long j=2,kr; /* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) */ - if (ierr==0) + if (ierr==0) { if (~strcmp(statevar,"t")){ // SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + SATT = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); + SATT(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); }else if (~strcmp(statevar,"p")){ // SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + SATP = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); + SATP(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); switch(ierr){ case 2: strcpy(errormsg,"P < Ptp"); @@ -867,13 +1027,15 @@ OUTPUT //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); }else if (~strcmp(statevar,"d")){ // SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + SATD = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); + SATD(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); switch(ierr){ case 2: strcpy(errormsg,"D > Dmax"); break; } } + } switch(ierr){ case 0: @@ -969,9 +1131,9 @@ OUTPUT //CONVERT TO SI-UNITS if (ierr==0){ - WMOLdll(xliq,wmliq); + WMOL(xliq,wmliq); wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); + WMOL(xvap,wmvap); wmvap /= 1000; //g/mol -> kg/mol //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); d *= wm*1000; //mol/dm� -> kg/m� diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp index 65b0501..ea92eac 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp @@ -89,7 +89,8 @@ int main(int argc, char* argv[]){ //strcpy(fluidname,argv[2]); strcpy(fluidname,"BUTANE"); //props is defined - double statevarval = 1e5; // 1 bar + double statevarval; // 1 bar + statevarval = 1e5; // 1 bar // x is defined char REFPROP_PATH[255]; strcpy(REFPROP_PATH,argv[5]); @@ -97,7 +98,21 @@ int main(int argc, char* argv[]){ double T; T = satprops_REFPROP (what, statevar, fluidname, props, statevarval, x, REFPROP_PATH, errormsg, DEBUG); printf("Saturation conditions for %s\t",fluidname); - printf("Saturation temperature =%f\t",T); + printf("Saturation temperature =%f\n\n",T); + + + strcpy(what, "T"); + strcpy(statevar, "p"); + strcpy(fluidname,"BUTANE"); + statevarval = 1.1e5; // 1 bar + strcpy(REFPROP_PATH,argv[5]); + + T = satprops_REFPROP (what, statevar, fluidname, props, statevarval, x, REFPROP_PATH, errormsg, DEBUG); + printf("Saturation conditions for %s\t",fluidname); + printf("Saturation temperature =%f\n\n",T); + + + printf("Errormessage: %s\n\n",errormsg); return 0; } From 2d0830167f6ed1e828ad25f7ec23b489c8900e9f Mon Sep 17 00:00:00 2001 From: jowr Date: Fri, 9 Nov 2012 03:26:54 -0800 Subject: [PATCH 11/57] 2012:11:09 12:25 - Fixed string length problems for fluid string passing --- .../src/refprop_wrapper.poco.cpp | 78 ++++++++++++++++--- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp index 1a624b2..087c252 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp @@ -51,6 +51,7 @@ // Some constants... +const long maxstringlength=10000; const long filepathlength=1024; const long errormessagelength=255+filepathlength; const long lengthofreference=3; @@ -87,12 +88,46 @@ SATTdll_POINTER SATT = NULL; SATPdll_POINTER SATP = NULL; SATDdll_POINTER SATD = NULL; +// char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { +// int i,n_ret; +// int newlen = strlen(replace); +// int oldlen = strlen(search); +// char *ret; +// *count = 0; +// +// //count occurrences of searchstring +// for (i = 0; oldlen && str[i]; ++i) +// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr +// ++*count, i+=oldlen - 1; +// } +// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); +// if (!ret){ +// printf("Could not allocate memory"); +// return ""; +// } +// +// if (!*count){ +// strncpy(ret,str,n_ret); +// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); +// }else{ +// i = 0; +// while (*str) +// if (strstr(str, search) == str) +// strncpy(&ret[i], replace,n_ret-i-1), +// i += newlen, +// str += oldlen; +// else +// ret[i++] = *str++; +// ret[i] = '\0'; +// } +// return ret; +// } //str_replace (fluidnames, "|", replace, nX) char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { *count = 0; - char ret[filepathlength]; + char ret[maxstringlength]; std::string fluids(str); std::string dlimit(search); @@ -122,6 +157,26 @@ return ret; } +// char printDoubleArray (double* arr[] ) { +// std::copy(arr.begin(),arr.end(),std::ostream_iterator(std::cout,", ")); +// } + +char *printX(double arr[], long nX) { + char ret[filepathlength]; + char tmp[filepathlength]; + strcpy(ret,"("); + //for(int i = 0; i < (sizeof(arr)-1); i++) { + for(int i = 0; i < (nX-2); i++) { + sprintf(tmp,"%f, ", arr[i]); + strcat(ret,tmp); + } + sprintf(tmp,"%f", arr[nX-1]); + strcat(ret,tmp); + + strcat(ret,")"); + //printf ("output: %s \n", ret); + return ret; +} int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ // Sets up the interface to the REFPROP.DLL @@ -296,7 +351,8 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr //if (DEBUGMODE) printf("REPLACE: %s\n",replace); strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); - int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; + //int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; + int hf_len = maxstringlength; hf = (char*) calloc(hf_len, sizeof(char)); strncpy(hf,FLD_PATH_CHAR,hf_len); @@ -325,7 +381,11 @@ int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr SETUPdll_POINTER SETUP = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); if (DEBUGMODE) printf("Running SETUP...\n"); - SETUP(*nX, hf, hfmix, hrf, ierr, herr); + //char hftmp[maxstringlength]; + //strcpy(hftmp,hf); + static char hfld[maxstringlength+1]; + strcpy(hfld,hf); + SETUP(*nX, hfld, hfmix, hrf, ierr, herr); strcpy(loadedfluids,fluidnames); strcpy(loadedpath,REF_PATH_CHAR); @@ -760,16 +820,16 @@ OUTPUT sprintf(errormsg,"T=%f and p=%f out of range",T,p); break; case 8: - strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(x,nX)); break; case 9: - sprintf(errormsg,"x or T=%f out of range",T); + sprintf(errormsg,"x=%s or T=%f out of range",printX(x,nX),T); break; case 12: - sprintf(errormsg,"x out of range and P=%f < 0",p); + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(x,nX),p); break; case 13: - sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(x,nX),T,p); break; case 16: strcpy(errormsg,"TPFLSH error: p>melting pressure"); @@ -1045,10 +1105,10 @@ OUTPUT sprintf(errormsg,"T=%f < Tmin",T); break; case 8: - strcpy(errormsg,"x out of range"); + sprintf(errormsg,"x out of range, %s",printX(x,nX)); break; case 9: - strcpy(errormsg,"T and x out of range"); + sprintf(errormsg,"T=%f and x=%s out of range",T,printX(x,nX)); break; case 10: strcpy(errormsg,"D and x out of range"); From a229ba5ea346b5d06d1350ee06f8d6b219a77ddd Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 13 Nov 2012 13:37:21 -0800 Subject: [PATCH 12/57] 2012:11:13 22:35 - Added a new wrapper file based on Ian Bell's CoolProp wrapper. It seems to work with Dymola... --- _REFPROP-Wrapper/Version 0.5_linux/Makefile | 12 +- .../Version 0.5_linux/src/refprop_wrapper.h | 3 + .../src/refprop_wrapper.ian.cpp | 1061 +++++++++++++++++ .../src/refpropwrappertest.cpp | 5 + package.mo | 2 +- readme.md | 4 +- 6 files changed, 1083 insertions(+), 4 deletions(-) create mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp diff --git a/_REFPROP-Wrapper/Version 0.5_linux/Makefile b/_REFPROP-Wrapper/Version 0.5_linux/Makefile index 657396a..ec954a4 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/Makefile +++ b/_REFPROP-Wrapper/Version 0.5_linux/Makefile @@ -103,7 +103,7 @@ $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION): $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENS .PHONY : library library : $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) -$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): poco +$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): ian .PHONY : nopoco nopoco : $(SRCDIR)/$(LIBFILE).org.o @@ -113,6 +113,10 @@ nopoco : $(SRCDIR)/$(LIBFILE).org.o poco : $(SRCDIR)/$(LIBFILE).poco.o $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).poco.o -lPocoFoundation +.PHONY : ian +ian : $(SRCDIR)/$(LIBFILE).ian.o + $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).ian.o -lPocoFoundation + ########################################################### # Compile the wrapper class tests. ########################################################### @@ -122,6 +126,12 @@ test : $(BINDIR)/$(THETEST) $(BINDIR)/$(THETEST) : $(SRCDIR)/$(THETEST).o $(CPPC) $(CPPFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).o $(LIBS) -l$(THENAME) +# .PHONY : ian +# ian : $(BINDIR)/$(THETEST).ian +# +# $(BINDIR)/$(THETEST).ian : $(SRCDIR)/$(THETEST).ian.o $(SRCDIR)/$(LIBFILE).ian.o +# $(CPPC) $(CPPFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).ian.o $(SRCDIR)/$(LIBFILE).ian.o -lPocoFoundation + ########################################################### # General rulesets for compilation. ########################################################### diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h index b672f42..19de850 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.h @@ -38,6 +38,9 @@ extern "C" { #endif // __cplusplus double props_REFPROP(char* what, char* statevars, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; + // + //double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, char * Ref); + double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char * Path, char * herr, int DEBUGMODE); #ifdef __cplusplus } #endif // __cplusplus diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp new file mode 100644 index 0000000..eba8238 --- /dev/null +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp @@ -0,0 +1,1061 @@ +/* + wrapper file for refprop. + + Based on earlier work by Henning Francke (francke@gfz-potsdam.de) + and the CoolProp wrapper by Ian Bell (ian.h.bell@gmail.com). + + "Copied and pasted" by Jorrit Wronski (jowr@mek.dtu.dk) + +*/ + +#if defined(WIN32) || defined(_WIN32) +#include +#endif + +// // #include "REFPROP.h" +// //#include "refprop_lib.h" +// #include "refprop_constants.h" +// #include "refprop_names.h" +// #include "refprop_cfunctions.h" +#define refpropcharlong 10000 +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +#include +#include +#include +#include +#include // tolower etc + +#include +//# error "Could not determine system." +#include "refprop_wrapper.h" + +// get the POCO classes +#include "Poco/SharedLibrary.h" +#include "Poco/Path.h" +#include "Poco/File.h" +#include "Poco/Environment.h" +#include "Poco/StringTokenizer.h" +#include "Poco/String.h" +#include "Poco/Exception.h" +// +// +// +ABFL1dll_POINTER ABFL1lib = NULL; +ABFL2dll_POINTER ABFL2lib = NULL; +ACTVYdll_POINTER ACTVYlib = NULL; +AGdll_POINTER AGlib = NULL; +CCRITdll_POINTER CCRITlib = NULL; +CP0dll_POINTER CP0lib = NULL; +CRITPdll_POINTER CRITPlib = NULL; +CSATKdll_POINTER CSATKlib = NULL; +CV2PKdll_POINTER CV2PKlib = NULL; +CVCPKdll_POINTER CVCPKlib = NULL; +CVCPdll_POINTER CVCPlib = NULL; +DBDTdll_POINTER DBDTlib = NULL; +DBFL1dll_POINTER DBFL1lib = NULL; +DBFL2dll_POINTER DBFL2lib = NULL; +DDDPdll_POINTER DDDPlib = NULL; +DDDTdll_POINTER DDDTlib = NULL; +DEFLSHdll_POINTER DEFLSHlib = NULL; +DHD1dll_POINTER DHD1lib = NULL; +DHFLSHdll_POINTER DHFLSHlib = NULL; +DIELECdll_POINTER DIELEClib = NULL; +DOTFILLdll_POINTER DOTFILLlib = NULL; +DPDD2dll_POINTER DPDD2lib = NULL; +DPDDKdll_POINTER DPDDKlib = NULL; +DPDDdll_POINTER DPDDlib = NULL; +DPDTKdll_POINTER DPDTKlib = NULL; +DPDTdll_POINTER DPDTlib = NULL; +DPTSATKdll_POINTER DPTSATKlib = NULL; +DSFLSHdll_POINTER DSFLSHlib = NULL; +ENTHALdll_POINTER ENTHALlib = NULL; //** +ENTROdll_POINTER ENTROlib = NULL; +ESFLSHdll_POINTER ESFLSHlib = NULL; +FGCTYdll_POINTER FGCTYlib = NULL; +FPVdll_POINTER FPVlib = NULL; +GERG04dll_POINTER GERG04lib = NULL; +GETFIJdll_POINTER GETFIJlib = NULL; +GETKTVdll_POINTER GETKTVlib = NULL; +GIBBSdll_POINTER GIBBSlib = NULL; +HSFLSHdll_POINTER HSFLSHlib = NULL; +INFOdll_POINTER INFOlib = NULL; +LIMITKdll_POINTER LIMITKlib = NULL; +LIMITSdll_POINTER LIMITSlib = NULL; +LIMITXdll_POINTER LIMITXlib = NULL; +MELTPdll_POINTER MELTPlib = NULL; +MELTTdll_POINTER MELTTlib = NULL; +MLTH2Odll_POINTER MLTH2Olib = NULL; +NAMEdll_POINTER NAMElib = NULL; +PDFL1dll_POINTER PDFL1lib = NULL; +PDFLSHdll_POINTER PDFLSHlib = NULL; +PEFLSHdll_POINTER PEFLSHlib = NULL; +PHFL1dll_POINTER PHFL1lib = NULL; +PHFLSHdll_POINTER PHFLSHlib = NULL; +PQFLSHdll_POINTER PQFLSHlib = NULL; +PREOSdll_POINTER PREOSlib = NULL; +PRESSdll_POINTER PRESSlib = NULL; +PSFL1dll_POINTER PSFL1lib = NULL; +PSFLSHdll_POINTER PSFLSHlib = NULL; +PUREFLDdll_POINTER PUREFLDlib = NULL; +QMASSdll_POINTER QMASSlib = NULL; +QMOLEdll_POINTER QMOLElib = NULL; +SATDdll_POINTER SATDlib = NULL; +SATEdll_POINTER SATElib = NULL; +SATHdll_POINTER SATHlib = NULL; +SATPdll_POINTER SATPlib = NULL; +SATSdll_POINTER SATSlib = NULL; +SATTdll_POINTER SATTlib = NULL; +SETAGAdll_POINTER SETAGAlib = NULL; +SETKTVdll_POINTER SETKTVlib = NULL; +SETMIXdll_POINTER SETMIXlib = NULL; +SETMODdll_POINTER SETMODlib = NULL; +SETREFdll_POINTER SETREFlib = NULL; +SETUPdll_POINTER SETUPlib = NULL; +//SPECGRdll_POINTER SPECGRlib = NULL; +SUBLPdll_POINTER SUBLPlib = NULL; +SUBLTdll_POINTER SUBLTlib = NULL; +SURFTdll_POINTER SURFTlib = NULL; +SURTENdll_POINTER SURTENlib = NULL; +TDFLSHdll_POINTER TDFLSHlib = NULL; +TEFLSHdll_POINTER TEFLSHlib = NULL; +THERM0dll_POINTER THERM0lib = NULL; +THERM2dll_POINTER THERM2lib = NULL; +THERM3dll_POINTER THERM3lib = NULL; +THERMdll_POINTER THERMlib = NULL; +THFLSHdll_POINTER THFLSHlib = NULL; +TPFLSHdll_POINTER TPFLSHlib = NULL; +TPRHOdll_POINTER TPRHOlib = NULL; +TQFLSHdll_POINTER TQFLSHlib = NULL; +TRNPRPdll_POINTER TRNPRPlib = NULL; +TSFLSHdll_POINTER TSFLSHlib = NULL; +VIRBdll_POINTER VIRBlib = NULL; +VIRCdll_POINTER VIRClib = NULL; +WMOLdll_POINTER WMOLlib = NULL; +XMASSdll_POINTER XMASSlib = NULL; +XMOLEdll_POINTER XMOLElib = NULL; + +// double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char * Path, char * herr, int DEBUGMODE); + +// Load the library +char LoadedREFPROPRef[2550]; +// HINSTANCE RefpropdllInstance=NULL; +Poco::SharedLibrary *RefpropdllInstance = NULL; + +// global variables for array +double T,p,d,dl,dv,dl_,dv_,q,e,h,s,cv,cp,w,MW,hl,hv,sl,sv,ul, + uv,pl,pv,hjt,eta,tcx,Q,Tcrit,pcrit,dcrit,rho,sigma; +double x[ncmax],xliq[ncmax],xvap[ncmax]; +long i,ierr; + +int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ +// Sets up the interface to the REFPROP.DLL +// is called by props_REFPROP and satprops_REFPROP +// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; +return 0; +} + +int getProps(double *props) { + double MWliq,MWvap; + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOLlib(xliq,MWliq); + WMOLlib(xvap,MWvap); + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr; //error code + props[1] = p*1000; //kPa -> Pa + props[2] = T; //Temperature in K + props[3] = MW/1000; //molecular weight, g/mol -> kg/mol + props[4] = d*MW; //density, mol/l -> kg/m3 + props[5] = dl*MWliq; //density of liquid phase, mol/l -> kg/m3 + props[6] = dv*MWvap; //density of vapour phase, mol/l -> kg/m3 + props[7] = q*MWvap/MW; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = e/MW; //inner energy, J/mol -> J/kg + props[9] = h/MW; //specific enthalpy, J/mol -> J/kg + props[10] = s/MW; //specific entropy, J/molK -> J/kgK + props[11] = cv/MW; // heat capacity + props[12] = cp/MW; // heat capacity + props[13] = w; //speed of sound + props[14] = MWliq/1000; + props[15] = MWvap/1000; + for (int ii=0;iifilepathlength){ + sprintf(herr,"Path too long (%i > %i)\n",strlen(RefpropPath),filepathlength); + return 0; + } + // Define temporary objects for checks. + Poco::Path REF_PATH(true); + + char FLUIDS_CHAR[filepathlength+1] = "fluids"; + Poco::Path FLD_PATH(true); + char LIBRARY_CHAR[filepathlength+1]; + Poco::Path LIB_PATH(true); + + // Parse the string and append a path separator if necessary. + REF_PATH.parse(RefpropPath, Poco::Path::PATH_NATIVE); + if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); + // Overwrite the provided path + strcpy(path,REF_PATH.toString().c_str()); + + // Check the path if running in debugmode + if (DEBUGMODE) { + Poco::File refFile(REF_PATH); + if ( !refFile.isDirectory() || !refFile.canRead() ){ + printf ("\nREF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + sprintf (herr,"\nREF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + return 0; + } else { + printf ("\nREF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); + } + } + + // The fluid files are in the Refprop directory, append "fluids". + FLD_PATH.parse(path); + FLD_PATH.pushDirectory(FLUIDS_CHAR); + + // First create a pointer to an instance of the library + // Then have windows load the library. + + Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... + // If REFPROP is not loaded, try to load it + if (RefpropdllInstance==NULL) + { + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); + // Check the OS and assign the right names for the library + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + strcpy(LIBRARY_CHAR,"librefprop.so"); + //SRC_PATH.parse("/usr/local/lib"); + } else { + strcpy(LIBRARY_CHAR,"refprop.dll"); + //SRC_PATH = REF_PATH; + } + SRC_PATH = REF_PATH; + + // search the library at the given path + bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); + if (found_lib) { + if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + } else { + if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + return 0; + } + + // check if the file is correct and executable + if (DEBUGMODE) { + Poco::File libFile(LIB_PATH); + if ( !libFile.isFile() || !libFile.canRead() ){ + printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + sprintf (herr,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + return 0; + } else { + printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); + } + } + + // load a new library instance + RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); + if (RefpropdllInstance==NULL) + { + printf("Could not load REFPROP. \n"); + return -1; + } + + //DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); + //DHFL1(d,h,x,T,ierr,herr,errormessagelength); + + //ABFL1dll_POINTER {aka void (*)(double&, double&, double*, long int&, double&, double&, double&, double&, double&, double&, long int&, char*, long int)}’ to ‘ + //ABFL1dll_TYPE {aka void (double&, double&, double*, long int&, double&, double&, double&, double&, double&, double&, long int&, char*, long int)}’ + + // Then get pointers into the dll to the actual functions. + ABFL1lib = (ABFL1dll_POINTER) RefpropdllInstance->getSymbol(ABFL1dll_NAME); + ABFL2lib = (ABFL2dll_POINTER) RefpropdllInstance->getSymbol(ABFL2dll_NAME); + ACTVYlib = (ACTVYdll_POINTER) RefpropdllInstance->getSymbol(ACTVYdll_NAME); + AGlib = (AGdll_POINTER) RefpropdllInstance->getSymbol(AGdll_NAME); + CCRITlib = (CCRITdll_POINTER) RefpropdllInstance->getSymbol(CCRITdll_NAME); + CP0lib = (CP0dll_POINTER) RefpropdllInstance->getSymbol(CP0dll_NAME); + CRITPlib = (CRITPdll_POINTER) RefpropdllInstance->getSymbol(CRITPdll_NAME); + CSATKlib = (CSATKdll_POINTER) RefpropdllInstance->getSymbol(CSATKdll_NAME); + CV2PKlib = (CV2PKdll_POINTER) RefpropdllInstance->getSymbol(CV2PKdll_NAME); + CVCPKlib = (CVCPKdll_POINTER) RefpropdllInstance->getSymbol(CVCPKdll_NAME); + CVCPlib = (CVCPdll_POINTER) RefpropdllInstance->getSymbol(CVCPdll_NAME); + DBDTlib = (DBDTdll_POINTER) RefpropdllInstance->getSymbol(DBDTdll_NAME); + DBFL1lib = (DBFL1dll_POINTER) RefpropdllInstance->getSymbol(DBFL1dll_NAME); + DBFL2lib = (DBFL2dll_POINTER) RefpropdllInstance->getSymbol(DBFL2dll_NAME); + DDDPlib = (DDDPdll_POINTER) RefpropdllInstance->getSymbol(DDDPdll_NAME); + DDDTlib = (DDDTdll_POINTER) RefpropdllInstance->getSymbol(DDDTdll_NAME); + DEFLSHlib = (DEFLSHdll_POINTER) RefpropdllInstance->getSymbol(DEFLSHdll_NAME); + DHD1lib = (DHD1dll_POINTER) RefpropdllInstance->getSymbol(DHD1dll_NAME); + DHFLSHlib = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); + DIELEClib = (DIELECdll_POINTER) RefpropdllInstance->getSymbol(DIELECdll_NAME); + DOTFILLlib = (DOTFILLdll_POINTER) RefpropdllInstance->getSymbol(DOTFILLdll_NAME); + DPDD2lib = (DPDD2dll_POINTER) RefpropdllInstance->getSymbol(DPDD2dll_NAME); + DPDDKlib = (DPDDKdll_POINTER) RefpropdllInstance->getSymbol(DPDDKdll_NAME); + DPDDlib = (DPDDdll_POINTER) RefpropdllInstance->getSymbol(DPDDdll_NAME); + DPDTKlib = (DPDTKdll_POINTER) RefpropdllInstance->getSymbol(DPDTKdll_NAME); + DPDTlib = (DPDTdll_POINTER) RefpropdllInstance->getSymbol(DPDTdll_NAME); + DPTSATKlib = (DPTSATKdll_POINTER) RefpropdllInstance->getSymbol(DPTSATKdll_NAME); + DSFLSHlib = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); + ENTHALlib = (ENTHALdll_POINTER) RefpropdllInstance->getSymbol(ENTHALdll_NAME); //** + ENTROlib = (ENTROdll_POINTER) RefpropdllInstance->getSymbol(ENTROdll_NAME); + ESFLSHlib = (ESFLSHdll_POINTER) RefpropdllInstance->getSymbol(ESFLSHdll_NAME); + FGCTYlib = (FGCTYdll_POINTER) RefpropdllInstance->getSymbol(FGCTYdll_NAME); + FPVlib = (FPVdll_POINTER) RefpropdllInstance->getSymbol(FPVdll_NAME); + GERG04lib = (GERG04dll_POINTER) RefpropdllInstance->getSymbol(GERG04dll_NAME); + GETFIJlib = (GETFIJdll_POINTER) RefpropdllInstance->getSymbol(GETFIJdll_NAME); + GETKTVlib = (GETKTVdll_POINTER) RefpropdllInstance->getSymbol(GETKTVdll_NAME); + GIBBSlib = (GIBBSdll_POINTER) RefpropdllInstance->getSymbol(GIBBSdll_NAME); + HSFLSHlib = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); + INFOlib = (INFOdll_POINTER) RefpropdllInstance->getSymbol(INFOdll_NAME); + LIMITKlib = (LIMITKdll_POINTER) RefpropdllInstance->getSymbol(LIMITKdll_NAME); + LIMITSlib = (LIMITSdll_POINTER) RefpropdllInstance->getSymbol(LIMITSdll_NAME); + LIMITXlib = (LIMITXdll_POINTER) RefpropdllInstance->getSymbol(LIMITXdll_NAME); + MELTPlib = (MELTPdll_POINTER) RefpropdllInstance->getSymbol(MELTPdll_NAME); + MELTTlib = (MELTTdll_POINTER) RefpropdllInstance->getSymbol(MELTTdll_NAME); + MLTH2Olib = (MLTH2Odll_POINTER) RefpropdllInstance->getSymbol(MLTH2Odll_NAME); + NAMElib = (NAMEdll_POINTER) RefpropdllInstance->getSymbol(NAMEdll_NAME); + PDFL1lib = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); + PDFLSHlib = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); + PEFLSHlib = (PEFLSHdll_POINTER) RefpropdllInstance->getSymbol(PEFLSHdll_NAME); + PHFL1lib = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); + PHFLSHlib = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); + PQFLSHlib = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); + PREOSlib = (PREOSdll_POINTER) RefpropdllInstance->getSymbol(PREOSdll_NAME); + PRESSlib = (PRESSdll_POINTER) RefpropdllInstance->getSymbol(PRESSdll_NAME); + PSFL1lib = (PSFL1dll_POINTER) RefpropdllInstance->getSymbol(PSFL1dll_NAME); + PSFLSHlib = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); + PUREFLDlib = (PUREFLDdll_POINTER) RefpropdllInstance->getSymbol(PUREFLDdll_NAME); + QMASSlib = (QMASSdll_POINTER) RefpropdllInstance->getSymbol(QMASSdll_NAME); + QMOLElib = (QMOLEdll_POINTER) RefpropdllInstance->getSymbol(QMOLEdll_NAME); + SATDlib = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); + SATElib = (SATEdll_POINTER) RefpropdllInstance->getSymbol(SATEdll_NAME); + SATHlib = (SATHdll_POINTER) RefpropdllInstance->getSymbol(SATHdll_NAME); + SATPlib = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); + SATSlib = (SATSdll_POINTER) RefpropdllInstance->getSymbol(SATSdll_NAME); + SATTlib = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); + SETAGAlib = (SETAGAdll_POINTER) RefpropdllInstance->getSymbol(SETAGAdll_NAME); + SETKTVlib = (SETKTVdll_POINTER) RefpropdllInstance->getSymbol(SETKTVdll_NAME); + SETMIXlib = (SETMIXdll_POINTER) RefpropdllInstance->getSymbol(SETMIXdll_NAME); + SETMODlib = (SETMODdll_POINTER) RefpropdllInstance->getSymbol(SETMODdll_NAME); + SETREFlib = (SETREFdll_POINTER) RefpropdllInstance->getSymbol(SETREFdll_NAME); + SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); +// SPECGRlib = (SPECGRdll_POINTER) RefpropdllInstance->getSymbol(SPECGRdll_NAME); + SUBLPlib = (SUBLPdll_POINTER) RefpropdllInstance->getSymbol(SUBLPdll_NAME); + SUBLTlib = (SUBLTdll_POINTER) RefpropdllInstance->getSymbol(SUBLTdll_NAME); + SURFTlib = (SURFTdll_POINTER) RefpropdllInstance->getSymbol(SURFTdll_NAME); + SURTENlib = (SURTENdll_POINTER) RefpropdllInstance->getSymbol(SURTENdll_NAME); + TDFLSHlib = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); + TEFLSHlib = (TEFLSHdll_POINTER) RefpropdllInstance->getSymbol(TEFLSHdll_NAME); + THERM0lib = (THERM0dll_POINTER) RefpropdllInstance->getSymbol(THERM0dll_NAME); + THERM2lib = (THERM2dll_POINTER) RefpropdllInstance->getSymbol(THERM2dll_NAME); + THERM3lib = (THERM3dll_POINTER) RefpropdllInstance->getSymbol(THERM3dll_NAME); + THERMlib = (THERMdll_POINTER) RefpropdllInstance->getSymbol(THERMdll_NAME); + THFLSHlib = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); + TPFLSHlib = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); + TPRHOlib = (TPRHOdll_POINTER) RefpropdllInstance->getSymbol(TPRHOdll_NAME); + TQFLSHlib = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); + TRNPRPlib = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); + TSFLSHlib = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); + VIRBlib = (VIRBdll_POINTER) RefpropdllInstance->getSymbol(VIRBdll_NAME); + VIRClib = (VIRCdll_POINTER) RefpropdllInstance->getSymbol(VIRCdll_NAME); + WMOLlib = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); + XMASSlib = (XMASSdll_POINTER) RefpropdllInstance->getSymbol(XMASSdll_NAME); + XMOLElib = (XMOLEdll_POINTER) RefpropdllInstance->getSymbol(XMOLEdll_NAME); + // + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "true"); + } else { // library was already loaded + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "true"); + } + + + // Now the library is loaded and we can start checkicng the fluid path + if (DEBUGMODE) { + Poco::File fldFile(FLD_PATH); + if ( !fldFile.isDirectory() || !fldFile.canRead() ){ + printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + sprintf (herr,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + return 0; + } else { + printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); + } + } + char FLD_PATH_CHAR[filepathlength+1]; + strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + + + // If the fluid name starts with the string "REFPROP-", chop off the "REFPROP-" + if (!strncmp(Ref,"REFPROP-",8)) + { + char *REFPROPRef=NULL,*RefCopy=NULL; + double prop; + + // Allocate space for refrigerant name + RefCopy=(char *)malloc(strlen(Ref)+1); + // Make a backup copy + strcpy(RefCopy,Ref); + // Chop off the "REFPROP-" + REFPROPRef = strtok(RefCopy,"-"); + REFPROPRef = strtok(NULL,"-"); + // Run with the stripped Refrigerant name + prop=REFPROP(Output,Name1,Prop1,Name2,Prop2,xkg,REFPROPRef,path,herr,DEBUGMODE); + // Free allocated memory + free(RefCopy); + // Return the new value + return prop; + } + + // find the delimiter + char *pointer; + pointer = strchr(Ref, '|'); + + if (!strncmp(Ref,"MIX",3)) + { + // Sample is "REFPROP-MIX:R32[0.697615]&R125[0.302385]" - this is R410A + char *REFPROPRef=NULL,*RefCopy=NULL,*Refs[20],*Refrigerant; + double molefraction; + + // Allocate space for refrigerant name + RefCopy=(char *)malloc(strlen(Ref)+1); + // Make a backup copy + strcpy(RefCopy,Ref); + // Chop off the "MIX" + REFPROPRef = strtok(RefCopy,":"); + i=1; + while (REFPROPRef!=NULL) + { + Refs[i-1]=strtok(NULL,"&"); + if (Refs[i-1]==NULL) + { + i--; + break; + } + else + i++; + } + // Check maximum number of components + if (i>ncmax){ + sprintf(herr,"Too many components (More than %i)\n",ncmax); + return 1; + } + //Flush out RefString + sprintf(RefString,""); + for (j=0;jncmax){ + sprintf(herr,"Too many components (More than %i)\n",ncmax); + return 1; + } + if (DEBUGMODE) printf("Mass-based mixture with %li components \n",i); + //Flush out RefString + sprintf(RefString,""); + for (j=0;j1) + { + fprintf(stderr,"Error: Accentric factor only defined for pure fluids\n"); + return 1; + } + INFOlib(i,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); + return acf; + } + else if (Output =='o') + { + double wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas; + // Dipole moment + if (i>1) + { + fprintf(stderr,"Error: Dipole moment only defined for pure fluids\n"); + return 1; + } + INFOlib(i,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); + return dip; + } + else if (Output=='R') + { + long icomp; + double wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas; + // Triple point temperature + icomp=1; + if (i>1) + { + fprintf(stderr,"Error: Triple point temperature only defined for pure fluids\n"); + return 200; + } + INFOlib(icomp,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); + return Ttriple; + } + else if (Output=='I') + { + if (Name1=='T'){ + SURFTlib(Prop1,dl,x,sigma,i,herr,errormessagelength); + return sigma/1000; + } + else{ + std::cout<< "If surface tension is the output, temperature must be the first input" << std::endl; + return 1; + } + } + + else if ((Name1=='T' && Name2=='P') || (Name2=='T' && Name1=='P')) + { + // T in K, P in Pa + if (Name1 == 'T'){ + T = Prop1; p = Prop2/1000; + } + else{ + p = Prop1/1000; T = Prop2; + } + + + // Use flash routine to find properties + TPFLSHlib(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + if (Output=='H') return h/MW; + else if (Output=='D') return d*MW; + else if (Output=='S') return s/MW; + else if (Output=='U') return e/MW; + else if (Output=='C') return cp/MW; + else if (Output=='O') return cv/MW; + else if (Output=='P') return p*1000; + else if (Output=='A') return w; + else if (Output=='V') + { + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return eta/1.0e6; //uPa-s to Pa-s + } + else if (Output=='L') + { + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return tcx/1000.0; //W/m-K to kW/m-K + } + else + return 1; + } + else if ((Name1=='T' && Name2=='D') || (Name2=='T' && Name1=='D')) + { + // T in K, D in kg/m^3 + if (Name1 == 'T'){ + T = Prop1; rho = Prop2/MW; + } + else{ + rho = Prop1/MW; T = Prop2; + } + + // This is the explicit formulation of the EOS + TDFLSHlib(T,rho,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + + if (Output=='P') + { + return p*1000; + } + if (Output=='H') + { + return h/MW; + } + else if (Output=='A') + { + return w; + } + else if (Output=='S') + { + return s/MW; + } + else if (Output=='U') + { + return (h-p/rho)/MW; + } + else if (Output=='C') + { + return cp/MW; + } + else if (Output=='O') + { + return cv/MW; + } + else if (Output=='V') + { + TRNPRPlib(T,rho,x,eta,tcx,ierr,herr,errormessagelength); + return eta/1.0e6; //uPa-s to Pa-s + } + else if (Output=='L') + { + TRNPRPlib(T,rho,x,eta,tcx,ierr,herr,errormessagelength); + return tcx/1000.0; //W/m-K to kW/m-K + } + else if (Output=='D') + { + return rho*MW; + } + else + return 1; + } + else if ((Name1=='T' && Name2=='Q') || (Name2=='T' && Name1=='Q')) + { + + if (Name1 == 'T'){ + T = Prop1; Q = Prop2; + } + else{ + Q = Prop1; T = Prop2; + } + + // Saturation Density + i=1; + SATTlib(T,x,i,pl,dl,dv_,xliq,xvap,ierr,herr,errormessagelength); + i=2; + SATTlib(T,x,i,pv,dl_,dv,xliq,xvap,ierr,herr,errormessagelength); + if (Output=='D') + { + return 1/(Q/dv+(1-Q)/dl)*MW; + } + else if (Output=='P') + { + return (pv*Q+pl*(1-Q))*1000; + } + else if (Output=='A') + { + rho=1/(Q/dv+(1-Q)/dl); + THERMlib(T,rho,x,p,e,h,s,cv,cp,w,hjt); + return w; + } + else if (Output=='H') + { + ENTHALlib(T,dl,xliq,hl); + ENTHALlib(T,dv,xvap,hv); + return (hv*Q+hl*(1-Q))/MW*1000; // J/kg to kJ/kg + } + else if (Output=='S') + { + ENTROlib(T,dl,xliq,sl); + ENTROlib(T,dv,xvap,sv); + return (sv*Q+sl*(1-Q))/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='U') + { + ENTHALlib(T,dl,xliq,hl); + ENTHALlib(T,dv,xvap,hv); + p=pv*Q+pl*(1-Q); + ul=hl-p/dl; + uv=hv-p/dv; + return (uv*Q+ul*(1-Q))/MW*1000; // J/kg to kJ/kg + } + else if (Output=='C') + { + d=1/(Q/dv+(1-Q)/dl); + CVCPlib(T,d,x,cv,cp); + return cp/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='O') + { + d=1/(Q/dv+(1-Q)/dl); + CVCPlib(T,d,x,cv,cp); + return cv/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='V') + { + d=1/(Q/dv+(1-Q)/dl); + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return eta/1.0e6; //uPa-s to Pa-s + } + else if (Output=='L') + { + d=1/(Q/dv+(1-Q)/dl); + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return tcx/1000.0; //W/m-K to kW/m-K + } + else + return 1; + } + else if ((Name1=='P' && Name2=='Q') || (Name2=='P' && Name1=='Q')) + { + + if (Name1 == 'P'){ + p = Prop1/1000; Q = Prop2; + } + else{ + Q = Prop1; p = Prop2/1000; + } + + // Saturation Density + SATPlib(p,x,i,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + if (Output=='T') + { + return T; + } + else if (Output=='D') + { + return 1/(Q/dv+(1-Q)/dl)*MW; + } + else if (Output=='P') + { + PRESSlib(T,dl,xliq,pl); + PRESSlib(T,dv,xvap,pv); + return (pv*Q+pl*(1-Q))*1000; + } + else if (Output=='H') + { + ENTHALlib(T,dl,xliq,hl); + ENTHALlib(T,dv,xvap,hv); + return (hv*Q+hl*(1-Q))/MW*1000; // J/kg to kJ/kg + } + else if (Output=='S') + { + ENTROlib(T,dl,xliq,sl); + ENTROlib(T,dv,xvap,sv); + return (sv*Q+sl*(1-Q))/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='U') + { + ENTHALlib(T,dl,xliq,hl); + ENTHALlib(T,dv,xvap,hv); + ul=hl-p/dl; + uv=hv-p/dv; + return (uv*Q+ul*(1-Q))/MW*1000; // J/kg to kJ/kg + } + else if (Output=='C') + { + d=1/(Q/dv+(1-Q)/dl); + CVCPlib(T,d,x,cv,cp); + return cp/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='O') + { + d=1/(Q/dv+(1-Q)/dl); + CVCPlib(T,d,x,cv,cp); + return cv/MW*1000; // J/kg-K to kJ/kg-K + } + else if (Output=='A') + { + rho=1/(Q/dv+(1-Q)/dl); + THERMlib(T,rho,x,p,e,h,s,cv,cp,w,hjt); + return w; + } + else if (Output=='V') + { + d=1/(Q/dv+(1-Q)/dl); + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return eta/1.0e6; //uPa-s to Pa-s + } + else if (Output=='L') + { + d=1/(Q/dv+(1-Q)/dl); + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return tcx; //W/m-K to kW/m-K + } + else + return 1; + } + else if ((Name1=='P' && Name2=='H') || (Name2=='P' && Name1=='H')) + { + // p in Pa, h in J/kg + if (Name1 == 'P'){ + p = Prop1/1000; h = Prop2*MW/1000; + } + else{ + h = Prop1*MW/1000; p = Prop2/1000; + } + + // Use flash routine to find properties + PHFLSHlib(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + if (Output=='H') return h/MW; + else if (Output=='T') return T; + else if (Output=='D') return d*MW; + else if (Output=='S') return s/MW; + else if (Output=='U') return e/MW; + else if (Output=='C') return cp/MW; + else if (Output=='O') return cv/MW; + else if (Output=='P') return p*1000; + else if (Output=='A') return w; + else if (Output=='V') + { + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return eta/1.0e6; //uPa-s to Pa-s + } + else if (Output=='L') + { + TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); + return tcx/1000.0; //W/m-K to kW/m-K + } + else + return 1; + } + else + return 1; +} +// #endif diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp index ea92eac..2fd571e 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp @@ -113,6 +113,11 @@ int main(int argc, char* argv[]){ printf("Errormessage: %s\n\n",errormsg); + + +// double dens; +// dens = REFPROP(char "D",char Name1, double Prop1, char Name2, double Prop2, char * Ref) + return 0; } diff --git a/package.mo b/package.mo index a773821..544bac1 100644 --- a/package.mo +++ b/package.mo @@ -1,7 +1,7 @@ within ; package MediaTwoPhaseMixture // constant String REFPROP_PATH = "d:\\Program Files (x86)\\REFPROP\\"; - constant String REFPROP_PATH = "/home/jowr/Documents/Fluids/refprop/v9.0/"; + constant String REFPROP_PATH = "/opt/refprop/"; annotation (version="0.2", uses(Modelica(version="3.2")), Documentation(info=" diff --git a/readme.md b/readme.md index 7bdb6da..43b7aa3 100644 --- a/readme.md +++ b/readme.md @@ -17,9 +17,9 @@ For installing on a Linux machine, please follow the instructions in the Makefil 1. After downloading and unzipping rename folder containing these files to "MediaTwoPhaseMixture". 2. Change the paths in _REFPROP-Wrapper/Version x.x_linux/Makefile to your needs. -3. Make sure to have the shared library "librefprop.so" available. You might want to check https://github.com/jowr/librefprop.so for details. +3. Make sure to have the shared library "librefprop.so" available in the same directory as the "fluids" folder. You might want to check https://github.com/jowr/librefprop.so for details. 4. Call "make all" and "sudo make install" as well as "sudo make fixit" to compile and install the wrapper library. -5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/home/user/Refprop/"; +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; To remove the files from your system, please use "sudo make uninstall". Please be aware that you might need a copy of the Poco C++ framework to compile future versions the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. From bc14c6ea235933429186ac9311f07072f8f9e680 Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 20 Nov 2012 05:32:44 -0800 Subject: [PATCH 13/57] 2012:11:20 14:31 - On the way to a better wrapper. Last version of 0.5, added links to readme and a link to coolprop to the wrapper file --- .../src/refprop_wrapper.ian.cpp | 104 +++++++++++------- .../src/refpropwrappertest.cpp | 2 +- readme.md | 11 +- 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp index eba8238..1a7669d 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp @@ -1,10 +1,14 @@ /* wrapper file for refprop. + Heavily based on the Refprop wrapper in CoolProp by + Ian Bell (ian.h.bell@gmail.com) - http://coolprop.sourceforge.net/ + + Compatible to the modelica interface developed by Based on earlier work by Henning Francke (francke@gfz-potsdam.de) and the CoolProp wrapper by Ian Bell (ian.h.bell@gmail.com). - "Copied and pasted" by Jorrit Wronski (jowr@mek.dtu.dk) + Changes to produce this file by Jorrit Wronski (jowr@mek.dtu.dk) */ @@ -42,9 +46,7 @@ #include "Poco/Path.h" #include "Poco/File.h" #include "Poco/Environment.h" -#include "Poco/StringTokenizer.h" #include "Poco/String.h" -#include "Poco/Exception.h" // // // @@ -238,9 +240,34 @@ return ret; } - -double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char* RefpropPath, char* herr, int DEBUGMODE) -{ +/* + * Calculate properties for the current conditions. Includes initialisation and check of + * the requested fluids. Since the input comes from Modelica, unit conversion functions are + * invoked if necessary. + * This function is based on the Refprop wrapper that comes with the CoolProp package + * written by Ian Bell (ian.h.bell@gmail.com). The software is an open-source fluid property + * calculator based on Helmholtz energy. It is available athttp://coolprop.sourceforge.net. + * + * Input parameters: + * Output : Which property are we looking for? This char is one of: + * Name1 : First input quantity + * Prop1 : Value of the first quantity + * Name2 : Second input quantity + * Prop2 : Value of the second quantity + * Xkg : Array of mass based composition fractions + * Fluids : Char specifying the fluids in the mixture + * RPath : Absolute path pointing to Refprop folder + * + * Output parameters: + * return : The requested property + * herr : Error message from Refprop + * + * Additional input: + * DEBUG : 0 or 1 to turn debug output off or on + * +*/ +//double REFPROP(char Output, char Name1, double Prop1, char Name2, double Prop2, double* Xkg, char * Ref, char* RefpropPath, char* herr, int DEBUG){ +double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char* RefpropPath, char* herr, int DEBUGMODE){ int j; i=0; ierr=0; @@ -589,40 +616,41 @@ double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, d { i=1; strcpy(RefString,""); + strcat(RefString,FLD_PATH_CHAR); strcat(RefString,Ref); - strcat(RefString,".ppf"); + strcat(RefString,".PPF"); x[0]=1.0; //Pseudo-Pure fluid } - else if (!strcmp(Ref,"R507A")) - { - i=2; - strcpy(RefString,"R23.fld|R116.fld"); - x[0]=0.62675; - x[1]=0.37325; - } - else if (!strcmp(Ref,"R410A")) - { - i=2; - strcpy(RefString,"R32.fld|R125.fld"); - x[0]=0.697615; - x[1]=0.302385; - } - else if (!strcmp(Ref,"R404A")) - { - i=3; - strcpy(RefString,"R125.fld|R134a.fld|R143a.fld"); - x[0]=0.35782; - x[1]=0.038264; - x[2]=0.60392; - } - else if (!strcmp(Ref,"Air")) - { - i=3; - strcpy(RefString,"Nitrogen.fld|Oxygen.fld|Argon.fld"); - x[0]=0.7812; - x[1]=0.2096; - x[2]=0.0092; - } +// else if (!strcmp(Ref,"R507A")) +// { +// i=2; +// strcpy(RefString,"R23.fld|R116.fld"); +// x[0]=0.62675; +// x[1]=0.37325; +// } +// else if (!strcmp(Ref,"R410A")) +// { +// i=2; +// strcpy(RefString,"R32.fld|R125.fld"); +// x[0]=0.697615; +// x[1]=0.302385; +// } +// else if (!strcmp(Ref,"R404A")) +// { +// i=3; +// strcpy(RefString,"R125.fld|R134a.fld|R143a.fld"); +// x[0]=0.35782; +// x[1]=0.038264; +// x[2]=0.60392; +// } +// else if (!strcmp(Ref,"Air")) +// { +// i=3; +// strcpy(RefString,"Nitrogen.fld|Oxygen.fld|Argon.fld"); +// x[0]=0.7812; +// x[1]=0.2096; +// x[2]=0.0092; +// } else { i=1; @@ -658,6 +686,8 @@ double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, d // If the name of the refrigerant doesn't match // that of the currently loaded refrigerant + if (DEBUGMODE) printf("Loaded fluids: %s \n",LoadedREFPROPRef); + if (DEBUGMODE) printf("New fluids: %s \n",Ref); if (strcmp(LoadedREFPROPRef,Ref)) { ierr=999; diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp index 2fd571e..439392a 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp @@ -21,7 +21,7 @@ int main(int argc, char* argv[]){ if (argc<5){ // printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); - printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/home/jowr/Documents/Fluids/Refprop/v9.0/\" .1\n"); + printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); return 1; } diff --git a/readme.md b/readme.md index 43b7aa3..998fedc 100644 --- a/readme.md +++ b/readme.md @@ -21,7 +21,14 @@ For installing on a Linux machine, please follow the instructions in the Makefil 4. Call "make all" and "sudo make install" as well as "sudo make fixit" to compile and install the wrapper library. 5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; -To remove the files from your system, please use "sudo make uninstall". Please be aware that you might need a copy of the Poco C++ framework to compile future versions the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. +To remove the files from your system, please use "sudo make uninstall". Please be aware that you need a copy of the Poco C++ framework to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. ## General Remarks -Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. \ No newline at end of file +Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. + +## Links +If you are interested in this kind of software, you might also consider the following projects: + +1. https://github.com/Heineken/REFPROP2Modelica (The original version of this library) +2. https://github.com/thorade/HelmholtzMedia (A Modelica implementation the Helmholtz functions) +3. http://coolprop.sourceforge.net/ (A free fluid property library also based on Helmholtz formulation) \ No newline at end of file From 649712948e124e4906dfe417fbef563027211a6f Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 20 Nov 2012 06:52:34 -0800 Subject: [PATCH 14/57] 2012:11:20 15:51 - Removed constants from wrapper file --- .../src/refprop_wrapper.ian.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp index 1a7669d..db303ea 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp +++ b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp @@ -21,15 +21,15 @@ // #include "refprop_constants.h" // #include "refprop_names.h" // #include "refprop_cfunctions.h" -#define refpropcharlong 10000 -// Some constants for REFPROP... defined by macros for ease of use -#define refpropcharlength 255 -#define filepathlength 255 -#define lengthofreference 3 -#define errormessagelength 255 -#define ncmax 20 // Note: ncmax is the max number of components -#define numparams 72 -#define maxcoefs 50 +//#define refpropcharlong 10000 +//// Some constants for REFPROP... defined by macros for ease of use +//#define refpropcharlength 255 +//#define filepathlength 255 +//#define lengthofreference 3 +//#define errormessagelength 255 +//#define ncmax 20 // Note: ncmax is the max number of components +//#define numparams 72 +//#define maxcoefs 50 #include #include From 89e2977263338168d810eec0f23e463048090e35 Mon Sep 17 00:00:00 2001 From: jowr Date: Sun, 25 Nov 2012 09:25:42 -0800 Subject: [PATCH 15/57] 2012:11:25 18:23 - Included a basic caching mechanism, needs to be refined. Unit conversion errors were removed as well. --- .../Version 0.5_linux/doc/Doxyfile | 1749 ----------------- _REFPROP-Wrapper/Version 0.5_linux/list.bsh | 17 - .../src/refprop_wrapper.ian.cpp | 1091 ---------- .../src/refprop_wrapper.org.cpp | 883 --------- .../src/refprop_wrapper.poco.cpp | 1252 ------------ .../v0.5}/REFPROP_dll.H | 0 .../v0.5}/REFPROP_wrapper.cpp | 0 .../v0.5}/REFPROP_wrapper.lib | Bin .../v0.5}/makefile.bat | 0 .../v0.5}/refprop_wrapper.h | 0 .../v0.5}/refpropwrappertest.cpp | 0 .../v0.6}/Makefile | 22 +- _wrapper/v0.6/src/refprop_wrapper.cpp | 1501 ++++++++++++++ .../v0.6}/src/refprop_wrapper.h | 5 +- .../v0.6}/src/refpropwrappertest.cpp | 44 +- readme.md | 20 +- 16 files changed, 1551 insertions(+), 5033 deletions(-) delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/list.bsh delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp delete mode 100644 _REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.poco.cpp rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/REFPROP_dll.H (100%) rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/REFPROP_wrapper.cpp (100%) rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/REFPROP_wrapper.lib (100%) rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/makefile.bat (100%) rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/refprop_wrapper.h (100%) rename {_REFPROP-Wrapper/Version 0.5 => _wrapper/v0.5}/refpropwrappertest.cpp (100%) rename {_REFPROP-Wrapper/Version 0.5_linux => _wrapper/v0.6}/Makefile (88%) create mode 100644 _wrapper/v0.6/src/refprop_wrapper.cpp rename {_REFPROP-Wrapper/Version 0.5_linux => _wrapper/v0.6}/src/refprop_wrapper.h (84%) rename {_REFPROP-Wrapper/Version 0.5_linux => _wrapper/v0.6}/src/refpropwrappertest.cpp (73%) diff --git a/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile b/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile deleted file mode 100644 index 7ec9879..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/doc/Doxyfile +++ /dev/null @@ -1,1749 +0,0 @@ -# Doxyfile 1.7.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "Refprop2Modelica - Linux" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 0.2 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "Porting Henning Francke's Refprop2Modelica to Dymola on Linux" - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = /mnt/crypt/Software/modelica/Dymola/dymola-icon-small.png - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = "/home/jowr/Documents/Modelica_Libraries/REFPROP2Modelica/_REFPROP-Wrapper/Version 0.5_linux/doc" - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = "/home/jowr/Documents/Modelica_Libraries/REFPROP2Modelica/_REFPROP-Wrapper/Version 0.5_linux" - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.for \ - *.vhd \ - *.vhdl - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/_REFPROP-Wrapper/Version 0.5_linux/list.bsh b/_REFPROP-Wrapper/Version 0.5_linux/list.bsh deleted file mode 100644 index b334bc6..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/list.bsh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -function defineFunction { - echo "$1_TYPE * $1 = ($1_TYPE *) library.getSymbol($1_NAME);" -} -# -## declare an array variable -# declare -a arr=(RPVersion SETPATHdll ABFL1dll ABFL2dll ACTVYdll AGdll CCRITdll CP0dll CRITPdll CSATKdll CV2PKdll CVCPKdll CVCPdll DBDTdll DBFL1dll DBFL2dll DDDPdll DDDTdll DEFLSHdll DHD1dll DHFLSHdll DHFL1dll DHFL2dll DIELECdll DOTFILLdll DPDD2dll DPDDKdll DPDDdll DPDTKdll DPDTdll DPTSATKdll DSFLSHdll DSFL1dll DSFL2dll ENTHALdll ENTROdll ESFLSHdll FGCTYdll FPVdll GERG04dll GETFIJdll GETKTVdll GIBBSdll HSFLSHdll INFOdll LIMITKdll LIMITSdll LIMITXdll MELTPdll MELTTdll MLTH2Odll NAMEdll PDFL1dll PDFLSHdll PEFLSHdll PHFL1dll PHFLSHdll PQFLSHdll PREOSdll PRESSdll PSFL1dll PSFLSHdll PUREFLDdll QMASSdll QMOLEdll SATDdll SATEdll SATHdll SATPdll SATSdll SATTdll SETAGAdll SETKTVdll SETMIXdll SETMODdll SETREFdll SETUPdll SPECGRdll SUBLPdll SUBLTdll SURFTdll SURTENdll TDFLSHdll TEFLSHdll THERM0dll THERM2dll THERM3dll THERMdll THFLSHdll TPFLSHdll TPFL2dll TPRHOdll TQFLSHdll TRNPRPdll TSFLSHdll VIRBdll VIRCdll WMOLdll XMASSdll XMOLEdll) -# These ones are used in the wrapper -declare -a arr=(WMOLdll TPFL2dll TPFLSHdll PHFL1dll PHFLSHdll PDFL1dll PDFLSHdll PSFLSHdll PQFLSHdll THFLSHdll TDFLSHdll TSFLSHdll TQFLSHdll DHFL1dll DHFL2dll DHFLSHdll HSFLSHdll DSFL1dll DSFL2dll DSFLSHdll TRNPRPdll SATTdll SATPdll SATDdll) -# -## now loop through the above array -for i in ${arr[@]} -do - defineFunction $i # or do whatever with individual element of the array -done - diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp deleted file mode 100644 index db303ea..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.ian.cpp +++ /dev/null @@ -1,1091 +0,0 @@ -/* - wrapper file for refprop. - - Heavily based on the Refprop wrapper in CoolProp by - Ian Bell (ian.h.bell@gmail.com) - http://coolprop.sourceforge.net/ - - Compatible to the modelica interface developed by - Based on earlier work by Henning Francke (francke@gfz-potsdam.de) - and the CoolProp wrapper by Ian Bell (ian.h.bell@gmail.com). - - Changes to produce this file by Jorrit Wronski (jowr@mek.dtu.dk) - -*/ - -#if defined(WIN32) || defined(_WIN32) -#include -#endif - -// // #include "REFPROP.h" -// //#include "refprop_lib.h" -// #include "refprop_constants.h" -// #include "refprop_names.h" -// #include "refprop_cfunctions.h" -//#define refpropcharlong 10000 -//// Some constants for REFPROP... defined by macros for ease of use -//#define refpropcharlength 255 -//#define filepathlength 255 -//#define lengthofreference 3 -//#define errormessagelength 255 -//#define ncmax 20 // Note: ncmax is the max number of components -//#define numparams 72 -//#define maxcoefs 50 - -#include -#include -#include -#include -#include // tolower etc - -#include -//# error "Could not determine system." -#include "refprop_wrapper.h" - -// get the POCO classes -#include "Poco/SharedLibrary.h" -#include "Poco/Path.h" -#include "Poco/File.h" -#include "Poco/Environment.h" -#include "Poco/String.h" -// -// -// -ABFL1dll_POINTER ABFL1lib = NULL; -ABFL2dll_POINTER ABFL2lib = NULL; -ACTVYdll_POINTER ACTVYlib = NULL; -AGdll_POINTER AGlib = NULL; -CCRITdll_POINTER CCRITlib = NULL; -CP0dll_POINTER CP0lib = NULL; -CRITPdll_POINTER CRITPlib = NULL; -CSATKdll_POINTER CSATKlib = NULL; -CV2PKdll_POINTER CV2PKlib = NULL; -CVCPKdll_POINTER CVCPKlib = NULL; -CVCPdll_POINTER CVCPlib = NULL; -DBDTdll_POINTER DBDTlib = NULL; -DBFL1dll_POINTER DBFL1lib = NULL; -DBFL2dll_POINTER DBFL2lib = NULL; -DDDPdll_POINTER DDDPlib = NULL; -DDDTdll_POINTER DDDTlib = NULL; -DEFLSHdll_POINTER DEFLSHlib = NULL; -DHD1dll_POINTER DHD1lib = NULL; -DHFLSHdll_POINTER DHFLSHlib = NULL; -DIELECdll_POINTER DIELEClib = NULL; -DOTFILLdll_POINTER DOTFILLlib = NULL; -DPDD2dll_POINTER DPDD2lib = NULL; -DPDDKdll_POINTER DPDDKlib = NULL; -DPDDdll_POINTER DPDDlib = NULL; -DPDTKdll_POINTER DPDTKlib = NULL; -DPDTdll_POINTER DPDTlib = NULL; -DPTSATKdll_POINTER DPTSATKlib = NULL; -DSFLSHdll_POINTER DSFLSHlib = NULL; -ENTHALdll_POINTER ENTHALlib = NULL; //** -ENTROdll_POINTER ENTROlib = NULL; -ESFLSHdll_POINTER ESFLSHlib = NULL; -FGCTYdll_POINTER FGCTYlib = NULL; -FPVdll_POINTER FPVlib = NULL; -GERG04dll_POINTER GERG04lib = NULL; -GETFIJdll_POINTER GETFIJlib = NULL; -GETKTVdll_POINTER GETKTVlib = NULL; -GIBBSdll_POINTER GIBBSlib = NULL; -HSFLSHdll_POINTER HSFLSHlib = NULL; -INFOdll_POINTER INFOlib = NULL; -LIMITKdll_POINTER LIMITKlib = NULL; -LIMITSdll_POINTER LIMITSlib = NULL; -LIMITXdll_POINTER LIMITXlib = NULL; -MELTPdll_POINTER MELTPlib = NULL; -MELTTdll_POINTER MELTTlib = NULL; -MLTH2Odll_POINTER MLTH2Olib = NULL; -NAMEdll_POINTER NAMElib = NULL; -PDFL1dll_POINTER PDFL1lib = NULL; -PDFLSHdll_POINTER PDFLSHlib = NULL; -PEFLSHdll_POINTER PEFLSHlib = NULL; -PHFL1dll_POINTER PHFL1lib = NULL; -PHFLSHdll_POINTER PHFLSHlib = NULL; -PQFLSHdll_POINTER PQFLSHlib = NULL; -PREOSdll_POINTER PREOSlib = NULL; -PRESSdll_POINTER PRESSlib = NULL; -PSFL1dll_POINTER PSFL1lib = NULL; -PSFLSHdll_POINTER PSFLSHlib = NULL; -PUREFLDdll_POINTER PUREFLDlib = NULL; -QMASSdll_POINTER QMASSlib = NULL; -QMOLEdll_POINTER QMOLElib = NULL; -SATDdll_POINTER SATDlib = NULL; -SATEdll_POINTER SATElib = NULL; -SATHdll_POINTER SATHlib = NULL; -SATPdll_POINTER SATPlib = NULL; -SATSdll_POINTER SATSlib = NULL; -SATTdll_POINTER SATTlib = NULL; -SETAGAdll_POINTER SETAGAlib = NULL; -SETKTVdll_POINTER SETKTVlib = NULL; -SETMIXdll_POINTER SETMIXlib = NULL; -SETMODdll_POINTER SETMODlib = NULL; -SETREFdll_POINTER SETREFlib = NULL; -SETUPdll_POINTER SETUPlib = NULL; -//SPECGRdll_POINTER SPECGRlib = NULL; -SUBLPdll_POINTER SUBLPlib = NULL; -SUBLTdll_POINTER SUBLTlib = NULL; -SURFTdll_POINTER SURFTlib = NULL; -SURTENdll_POINTER SURTENlib = NULL; -TDFLSHdll_POINTER TDFLSHlib = NULL; -TEFLSHdll_POINTER TEFLSHlib = NULL; -THERM0dll_POINTER THERM0lib = NULL; -THERM2dll_POINTER THERM2lib = NULL; -THERM3dll_POINTER THERM3lib = NULL; -THERMdll_POINTER THERMlib = NULL; -THFLSHdll_POINTER THFLSHlib = NULL; -TPFLSHdll_POINTER TPFLSHlib = NULL; -TPRHOdll_POINTER TPRHOlib = NULL; -TQFLSHdll_POINTER TQFLSHlib = NULL; -TRNPRPdll_POINTER TRNPRPlib = NULL; -TSFLSHdll_POINTER TSFLSHlib = NULL; -VIRBdll_POINTER VIRBlib = NULL; -VIRCdll_POINTER VIRClib = NULL; -WMOLdll_POINTER WMOLlib = NULL; -XMASSdll_POINTER XMASSlib = NULL; -XMOLEdll_POINTER XMOLElib = NULL; - -// double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char * Path, char * herr, int DEBUGMODE); - -// Load the library -char LoadedREFPROPRef[2550]; -// HINSTANCE RefpropdllInstance=NULL; -Poco::SharedLibrary *RefpropdllInstance = NULL; - -// global variables for array -double T,p,d,dl,dv,dl_,dv_,q,e,h,s,cv,cp,w,MW,hl,hv,sl,sv,ul, - uv,pl,pv,hjt,eta,tcx,Q,Tcrit,pcrit,dcrit,rho,sigma; -double x[ncmax],xliq[ncmax],xvap[ncmax]; -long i,ierr; - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP -// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; -return 0; -} - -int getProps(double *props) { - double MWliq,MWvap; - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLlib(xliq,MWliq); - WMOLlib(xvap,MWvap); - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr; //error code - props[1] = p*1000; //kPa -> Pa - props[2] = T; //Temperature in K - props[3] = MW/1000; //molecular weight, g/mol -> kg/mol - props[4] = d*MW; //density, mol/l -> kg/m3 - props[5] = dl*MWliq; //density of liquid phase, mol/l -> kg/m3 - props[6] = dv*MWvap; //density of vapour phase, mol/l -> kg/m3 - props[7] = q*MWvap/MW; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e/MW; //inner energy, J/mol -> J/kg - props[9] = h/MW; //specific enthalpy, J/mol -> J/kg - props[10] = s/MW; //specific entropy, J/molK -> J/kgK - props[11] = cv/MW; // heat capacity - props[12] = cp/MW; // heat capacity - props[13] = w; //speed of sound - props[14] = MWliq/1000; - props[15] = MWvap/1000; - for (int ii=0;iifilepathlength){ - sprintf(herr,"Path too long (%i > %i)\n",strlen(RefpropPath),filepathlength); - return 0; - } - // Define temporary objects for checks. - Poco::Path REF_PATH(true); - - char FLUIDS_CHAR[filepathlength+1] = "fluids"; - Poco::Path FLD_PATH(true); - char LIBRARY_CHAR[filepathlength+1]; - Poco::Path LIB_PATH(true); - - // Parse the string and append a path separator if necessary. - REF_PATH.parse(RefpropPath, Poco::Path::PATH_NATIVE); - if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); - // Overwrite the provided path - strcpy(path,REF_PATH.toString().c_str()); - - // Check the path if running in debugmode - if (DEBUGMODE) { - Poco::File refFile(REF_PATH); - if ( !refFile.isDirectory() || !refFile.canRead() ){ - printf ("\nREF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - sprintf (herr,"\nREF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - return 0; - } else { - printf ("\nREF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); - } - } - - // The fluid files are in the Refprop directory, append "fluids". - FLD_PATH.parse(path); - FLD_PATH.pushDirectory(FLUIDS_CHAR); - - // First create a pointer to an instance of the library - // Then have windows load the library. - - Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... - // If REFPROP is not loaded, try to load it - if (RefpropdllInstance==NULL) - { - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); - // Check the OS and assign the right names for the library - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - strcpy(LIBRARY_CHAR,"librefprop.so"); - //SRC_PATH.parse("/usr/local/lib"); - } else { - strcpy(LIBRARY_CHAR,"refprop.dll"); - //SRC_PATH = REF_PATH; - } - SRC_PATH = REF_PATH; - - // search the library at the given path - bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); - if (found_lib) { - if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - } else { - if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - return 0; - } - - // check if the file is correct and executable - if (DEBUGMODE) { - Poco::File libFile(LIB_PATH); - if ( !libFile.isFile() || !libFile.canRead() ){ - printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - sprintf (herr,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - return 0; - } else { - printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); - } - } - - // load a new library instance - RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); - if (RefpropdllInstance==NULL) - { - printf("Could not load REFPROP. \n"); - return -1; - } - - //DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); - //DHFL1(d,h,x,T,ierr,herr,errormessagelength); - - //ABFL1dll_POINTER {aka void (*)(double&, double&, double*, long int&, double&, double&, double&, double&, double&, double&, long int&, char*, long int)}’ to ‘ - //ABFL1dll_TYPE {aka void (double&, double&, double*, long int&, double&, double&, double&, double&, double&, double&, long int&, char*, long int)}’ - - // Then get pointers into the dll to the actual functions. - ABFL1lib = (ABFL1dll_POINTER) RefpropdllInstance->getSymbol(ABFL1dll_NAME); - ABFL2lib = (ABFL2dll_POINTER) RefpropdllInstance->getSymbol(ABFL2dll_NAME); - ACTVYlib = (ACTVYdll_POINTER) RefpropdllInstance->getSymbol(ACTVYdll_NAME); - AGlib = (AGdll_POINTER) RefpropdllInstance->getSymbol(AGdll_NAME); - CCRITlib = (CCRITdll_POINTER) RefpropdllInstance->getSymbol(CCRITdll_NAME); - CP0lib = (CP0dll_POINTER) RefpropdllInstance->getSymbol(CP0dll_NAME); - CRITPlib = (CRITPdll_POINTER) RefpropdllInstance->getSymbol(CRITPdll_NAME); - CSATKlib = (CSATKdll_POINTER) RefpropdllInstance->getSymbol(CSATKdll_NAME); - CV2PKlib = (CV2PKdll_POINTER) RefpropdllInstance->getSymbol(CV2PKdll_NAME); - CVCPKlib = (CVCPKdll_POINTER) RefpropdllInstance->getSymbol(CVCPKdll_NAME); - CVCPlib = (CVCPdll_POINTER) RefpropdllInstance->getSymbol(CVCPdll_NAME); - DBDTlib = (DBDTdll_POINTER) RefpropdllInstance->getSymbol(DBDTdll_NAME); - DBFL1lib = (DBFL1dll_POINTER) RefpropdllInstance->getSymbol(DBFL1dll_NAME); - DBFL2lib = (DBFL2dll_POINTER) RefpropdllInstance->getSymbol(DBFL2dll_NAME); - DDDPlib = (DDDPdll_POINTER) RefpropdllInstance->getSymbol(DDDPdll_NAME); - DDDTlib = (DDDTdll_POINTER) RefpropdllInstance->getSymbol(DDDTdll_NAME); - DEFLSHlib = (DEFLSHdll_POINTER) RefpropdllInstance->getSymbol(DEFLSHdll_NAME); - DHD1lib = (DHD1dll_POINTER) RefpropdllInstance->getSymbol(DHD1dll_NAME); - DHFLSHlib = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); - DIELEClib = (DIELECdll_POINTER) RefpropdllInstance->getSymbol(DIELECdll_NAME); - DOTFILLlib = (DOTFILLdll_POINTER) RefpropdllInstance->getSymbol(DOTFILLdll_NAME); - DPDD2lib = (DPDD2dll_POINTER) RefpropdllInstance->getSymbol(DPDD2dll_NAME); - DPDDKlib = (DPDDKdll_POINTER) RefpropdllInstance->getSymbol(DPDDKdll_NAME); - DPDDlib = (DPDDdll_POINTER) RefpropdllInstance->getSymbol(DPDDdll_NAME); - DPDTKlib = (DPDTKdll_POINTER) RefpropdllInstance->getSymbol(DPDTKdll_NAME); - DPDTlib = (DPDTdll_POINTER) RefpropdllInstance->getSymbol(DPDTdll_NAME); - DPTSATKlib = (DPTSATKdll_POINTER) RefpropdllInstance->getSymbol(DPTSATKdll_NAME); - DSFLSHlib = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); - ENTHALlib = (ENTHALdll_POINTER) RefpropdllInstance->getSymbol(ENTHALdll_NAME); //** - ENTROlib = (ENTROdll_POINTER) RefpropdllInstance->getSymbol(ENTROdll_NAME); - ESFLSHlib = (ESFLSHdll_POINTER) RefpropdllInstance->getSymbol(ESFLSHdll_NAME); - FGCTYlib = (FGCTYdll_POINTER) RefpropdllInstance->getSymbol(FGCTYdll_NAME); - FPVlib = (FPVdll_POINTER) RefpropdllInstance->getSymbol(FPVdll_NAME); - GERG04lib = (GERG04dll_POINTER) RefpropdllInstance->getSymbol(GERG04dll_NAME); - GETFIJlib = (GETFIJdll_POINTER) RefpropdllInstance->getSymbol(GETFIJdll_NAME); - GETKTVlib = (GETKTVdll_POINTER) RefpropdllInstance->getSymbol(GETKTVdll_NAME); - GIBBSlib = (GIBBSdll_POINTER) RefpropdllInstance->getSymbol(GIBBSdll_NAME); - HSFLSHlib = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); - INFOlib = (INFOdll_POINTER) RefpropdllInstance->getSymbol(INFOdll_NAME); - LIMITKlib = (LIMITKdll_POINTER) RefpropdllInstance->getSymbol(LIMITKdll_NAME); - LIMITSlib = (LIMITSdll_POINTER) RefpropdllInstance->getSymbol(LIMITSdll_NAME); - LIMITXlib = (LIMITXdll_POINTER) RefpropdllInstance->getSymbol(LIMITXdll_NAME); - MELTPlib = (MELTPdll_POINTER) RefpropdllInstance->getSymbol(MELTPdll_NAME); - MELTTlib = (MELTTdll_POINTER) RefpropdllInstance->getSymbol(MELTTdll_NAME); - MLTH2Olib = (MLTH2Odll_POINTER) RefpropdllInstance->getSymbol(MLTH2Odll_NAME); - NAMElib = (NAMEdll_POINTER) RefpropdllInstance->getSymbol(NAMEdll_NAME); - PDFL1lib = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); - PDFLSHlib = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); - PEFLSHlib = (PEFLSHdll_POINTER) RefpropdllInstance->getSymbol(PEFLSHdll_NAME); - PHFL1lib = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); - PHFLSHlib = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); - PQFLSHlib = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); - PREOSlib = (PREOSdll_POINTER) RefpropdllInstance->getSymbol(PREOSdll_NAME); - PRESSlib = (PRESSdll_POINTER) RefpropdllInstance->getSymbol(PRESSdll_NAME); - PSFL1lib = (PSFL1dll_POINTER) RefpropdllInstance->getSymbol(PSFL1dll_NAME); - PSFLSHlib = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); - PUREFLDlib = (PUREFLDdll_POINTER) RefpropdllInstance->getSymbol(PUREFLDdll_NAME); - QMASSlib = (QMASSdll_POINTER) RefpropdllInstance->getSymbol(QMASSdll_NAME); - QMOLElib = (QMOLEdll_POINTER) RefpropdllInstance->getSymbol(QMOLEdll_NAME); - SATDlib = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); - SATElib = (SATEdll_POINTER) RefpropdllInstance->getSymbol(SATEdll_NAME); - SATHlib = (SATHdll_POINTER) RefpropdllInstance->getSymbol(SATHdll_NAME); - SATPlib = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); - SATSlib = (SATSdll_POINTER) RefpropdllInstance->getSymbol(SATSdll_NAME); - SATTlib = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); - SETAGAlib = (SETAGAdll_POINTER) RefpropdllInstance->getSymbol(SETAGAdll_NAME); - SETKTVlib = (SETKTVdll_POINTER) RefpropdllInstance->getSymbol(SETKTVdll_NAME); - SETMIXlib = (SETMIXdll_POINTER) RefpropdllInstance->getSymbol(SETMIXdll_NAME); - SETMODlib = (SETMODdll_POINTER) RefpropdllInstance->getSymbol(SETMODdll_NAME); - SETREFlib = (SETREFdll_POINTER) RefpropdllInstance->getSymbol(SETREFdll_NAME); - SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); -// SPECGRlib = (SPECGRdll_POINTER) RefpropdllInstance->getSymbol(SPECGRdll_NAME); - SUBLPlib = (SUBLPdll_POINTER) RefpropdllInstance->getSymbol(SUBLPdll_NAME); - SUBLTlib = (SUBLTdll_POINTER) RefpropdllInstance->getSymbol(SUBLTdll_NAME); - SURFTlib = (SURFTdll_POINTER) RefpropdllInstance->getSymbol(SURFTdll_NAME); - SURTENlib = (SURTENdll_POINTER) RefpropdllInstance->getSymbol(SURTENdll_NAME); - TDFLSHlib = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); - TEFLSHlib = (TEFLSHdll_POINTER) RefpropdllInstance->getSymbol(TEFLSHdll_NAME); - THERM0lib = (THERM0dll_POINTER) RefpropdllInstance->getSymbol(THERM0dll_NAME); - THERM2lib = (THERM2dll_POINTER) RefpropdllInstance->getSymbol(THERM2dll_NAME); - THERM3lib = (THERM3dll_POINTER) RefpropdllInstance->getSymbol(THERM3dll_NAME); - THERMlib = (THERMdll_POINTER) RefpropdllInstance->getSymbol(THERMdll_NAME); - THFLSHlib = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); - TPFLSHlib = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); - TPRHOlib = (TPRHOdll_POINTER) RefpropdllInstance->getSymbol(TPRHOdll_NAME); - TQFLSHlib = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); - TRNPRPlib = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); - TSFLSHlib = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); - VIRBlib = (VIRBdll_POINTER) RefpropdllInstance->getSymbol(VIRBdll_NAME); - VIRClib = (VIRCdll_POINTER) RefpropdllInstance->getSymbol(VIRCdll_NAME); - WMOLlib = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); - XMASSlib = (XMASSdll_POINTER) RefpropdllInstance->getSymbol(XMASSdll_NAME); - XMOLElib = (XMOLEdll_POINTER) RefpropdllInstance->getSymbol(XMOLEdll_NAME); - // - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "true"); - } else { // library was already loaded - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "true"); - } - - - // Now the library is loaded and we can start checkicng the fluid path - if (DEBUGMODE) { - Poco::File fldFile(FLD_PATH); - if ( !fldFile.isDirectory() || !fldFile.canRead() ){ - printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - sprintf (herr,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return 0; - } else { - printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); - } - } - char FLD_PATH_CHAR[filepathlength+1]; - strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - - - // If the fluid name starts with the string "REFPROP-", chop off the "REFPROP-" - if (!strncmp(Ref,"REFPROP-",8)) - { - char *REFPROPRef=NULL,*RefCopy=NULL; - double prop; - - // Allocate space for refrigerant name - RefCopy=(char *)malloc(strlen(Ref)+1); - // Make a backup copy - strcpy(RefCopy,Ref); - // Chop off the "REFPROP-" - REFPROPRef = strtok(RefCopy,"-"); - REFPROPRef = strtok(NULL,"-"); - // Run with the stripped Refrigerant name - prop=REFPROP(Output,Name1,Prop1,Name2,Prop2,xkg,REFPROPRef,path,herr,DEBUGMODE); - // Free allocated memory - free(RefCopy); - // Return the new value - return prop; - } - - // find the delimiter - char *pointer; - pointer = strchr(Ref, '|'); - - if (!strncmp(Ref,"MIX",3)) - { - // Sample is "REFPROP-MIX:R32[0.697615]&R125[0.302385]" - this is R410A - char *REFPROPRef=NULL,*RefCopy=NULL,*Refs[20],*Refrigerant; - double molefraction; - - // Allocate space for refrigerant name - RefCopy=(char *)malloc(strlen(Ref)+1); - // Make a backup copy - strcpy(RefCopy,Ref); - // Chop off the "MIX" - REFPROPRef = strtok(RefCopy,":"); - i=1; - while (REFPROPRef!=NULL) - { - Refs[i-1]=strtok(NULL,"&"); - if (Refs[i-1]==NULL) - { - i--; - break; - } - else - i++; - } - // Check maximum number of components - if (i>ncmax){ - sprintf(herr,"Too many components (More than %i)\n",ncmax); - return 1; - } - //Flush out RefString - sprintf(RefString,""); - for (j=0;jncmax){ - sprintf(herr,"Too many components (More than %i)\n",ncmax); - return 1; - } - if (DEBUGMODE) printf("Mass-based mixture with %li components \n",i); - //Flush out RefString - sprintf(RefString,""); - for (j=0;j1) - { - fprintf(stderr,"Error: Accentric factor only defined for pure fluids\n"); - return 1; - } - INFOlib(i,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); - return acf; - } - else if (Output =='o') - { - double wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas; - // Dipole moment - if (i>1) - { - fprintf(stderr,"Error: Dipole moment only defined for pure fluids\n"); - return 1; - } - INFOlib(i,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); - return dip; - } - else if (Output=='R') - { - long icomp; - double wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas; - // Triple point temperature - icomp=1; - if (i>1) - { - fprintf(stderr,"Error: Triple point temperature only defined for pure fluids\n"); - return 200; - } - INFOlib(icomp,wmm,Ttriple,tnbpt,tc,pc,Dc,Zc,acf,dip,Rgas); - return Ttriple; - } - else if (Output=='I') - { - if (Name1=='T'){ - SURFTlib(Prop1,dl,x,sigma,i,herr,errormessagelength); - return sigma/1000; - } - else{ - std::cout<< "If surface tension is the output, temperature must be the first input" << std::endl; - return 1; - } - } - - else if ((Name1=='T' && Name2=='P') || (Name2=='T' && Name1=='P')) - { - // T in K, P in Pa - if (Name1 == 'T'){ - T = Prop1; p = Prop2/1000; - } - else{ - p = Prop1/1000; T = Prop2; - } - - - // Use flash routine to find properties - TPFLSHlib(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - if (Output=='H') return h/MW; - else if (Output=='D') return d*MW; - else if (Output=='S') return s/MW; - else if (Output=='U') return e/MW; - else if (Output=='C') return cp/MW; - else if (Output=='O') return cv/MW; - else if (Output=='P') return p*1000; - else if (Output=='A') return w; - else if (Output=='V') - { - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return eta/1.0e6; //uPa-s to Pa-s - } - else if (Output=='L') - { - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return tcx/1000.0; //W/m-K to kW/m-K - } - else - return 1; - } - else if ((Name1=='T' && Name2=='D') || (Name2=='T' && Name1=='D')) - { - // T in K, D in kg/m^3 - if (Name1 == 'T'){ - T = Prop1; rho = Prop2/MW; - } - else{ - rho = Prop1/MW; T = Prop2; - } - - // This is the explicit formulation of the EOS - TDFLSHlib(T,rho,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - - if (Output=='P') - { - return p*1000; - } - if (Output=='H') - { - return h/MW; - } - else if (Output=='A') - { - return w; - } - else if (Output=='S') - { - return s/MW; - } - else if (Output=='U') - { - return (h-p/rho)/MW; - } - else if (Output=='C') - { - return cp/MW; - } - else if (Output=='O') - { - return cv/MW; - } - else if (Output=='V') - { - TRNPRPlib(T,rho,x,eta,tcx,ierr,herr,errormessagelength); - return eta/1.0e6; //uPa-s to Pa-s - } - else if (Output=='L') - { - TRNPRPlib(T,rho,x,eta,tcx,ierr,herr,errormessagelength); - return tcx/1000.0; //W/m-K to kW/m-K - } - else if (Output=='D') - { - return rho*MW; - } - else - return 1; - } - else if ((Name1=='T' && Name2=='Q') || (Name2=='T' && Name1=='Q')) - { - - if (Name1 == 'T'){ - T = Prop1; Q = Prop2; - } - else{ - Q = Prop1; T = Prop2; - } - - // Saturation Density - i=1; - SATTlib(T,x,i,pl,dl,dv_,xliq,xvap,ierr,herr,errormessagelength); - i=2; - SATTlib(T,x,i,pv,dl_,dv,xliq,xvap,ierr,herr,errormessagelength); - if (Output=='D') - { - return 1/(Q/dv+(1-Q)/dl)*MW; - } - else if (Output=='P') - { - return (pv*Q+pl*(1-Q))*1000; - } - else if (Output=='A') - { - rho=1/(Q/dv+(1-Q)/dl); - THERMlib(T,rho,x,p,e,h,s,cv,cp,w,hjt); - return w; - } - else if (Output=='H') - { - ENTHALlib(T,dl,xliq,hl); - ENTHALlib(T,dv,xvap,hv); - return (hv*Q+hl*(1-Q))/MW*1000; // J/kg to kJ/kg - } - else if (Output=='S') - { - ENTROlib(T,dl,xliq,sl); - ENTROlib(T,dv,xvap,sv); - return (sv*Q+sl*(1-Q))/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='U') - { - ENTHALlib(T,dl,xliq,hl); - ENTHALlib(T,dv,xvap,hv); - p=pv*Q+pl*(1-Q); - ul=hl-p/dl; - uv=hv-p/dv; - return (uv*Q+ul*(1-Q))/MW*1000; // J/kg to kJ/kg - } - else if (Output=='C') - { - d=1/(Q/dv+(1-Q)/dl); - CVCPlib(T,d,x,cv,cp); - return cp/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='O') - { - d=1/(Q/dv+(1-Q)/dl); - CVCPlib(T,d,x,cv,cp); - return cv/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='V') - { - d=1/(Q/dv+(1-Q)/dl); - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return eta/1.0e6; //uPa-s to Pa-s - } - else if (Output=='L') - { - d=1/(Q/dv+(1-Q)/dl); - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return tcx/1000.0; //W/m-K to kW/m-K - } - else - return 1; - } - else if ((Name1=='P' && Name2=='Q') || (Name2=='P' && Name1=='Q')) - { - - if (Name1 == 'P'){ - p = Prop1/1000; Q = Prop2; - } - else{ - Q = Prop1; p = Prop2/1000; - } - - // Saturation Density - SATPlib(p,x,i,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - if (Output=='T') - { - return T; - } - else if (Output=='D') - { - return 1/(Q/dv+(1-Q)/dl)*MW; - } - else if (Output=='P') - { - PRESSlib(T,dl,xliq,pl); - PRESSlib(T,dv,xvap,pv); - return (pv*Q+pl*(1-Q))*1000; - } - else if (Output=='H') - { - ENTHALlib(T,dl,xliq,hl); - ENTHALlib(T,dv,xvap,hv); - return (hv*Q+hl*(1-Q))/MW*1000; // J/kg to kJ/kg - } - else if (Output=='S') - { - ENTROlib(T,dl,xliq,sl); - ENTROlib(T,dv,xvap,sv); - return (sv*Q+sl*(1-Q))/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='U') - { - ENTHALlib(T,dl,xliq,hl); - ENTHALlib(T,dv,xvap,hv); - ul=hl-p/dl; - uv=hv-p/dv; - return (uv*Q+ul*(1-Q))/MW*1000; // J/kg to kJ/kg - } - else if (Output=='C') - { - d=1/(Q/dv+(1-Q)/dl); - CVCPlib(T,d,x,cv,cp); - return cp/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='O') - { - d=1/(Q/dv+(1-Q)/dl); - CVCPlib(T,d,x,cv,cp); - return cv/MW*1000; // J/kg-K to kJ/kg-K - } - else if (Output=='A') - { - rho=1/(Q/dv+(1-Q)/dl); - THERMlib(T,rho,x,p,e,h,s,cv,cp,w,hjt); - return w; - } - else if (Output=='V') - { - d=1/(Q/dv+(1-Q)/dl); - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return eta/1.0e6; //uPa-s to Pa-s - } - else if (Output=='L') - { - d=1/(Q/dv+(1-Q)/dl); - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return tcx; //W/m-K to kW/m-K - } - else - return 1; - } - else if ((Name1=='P' && Name2=='H') || (Name2=='P' && Name1=='H')) - { - // p in Pa, h in J/kg - if (Name1 == 'P'){ - p = Prop1/1000; h = Prop2*MW/1000; - } - else{ - h = Prop1*MW/1000; p = Prop2/1000; - } - - // Use flash routine to find properties - PHFLSHlib(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - if (Output=='H') return h/MW; - else if (Output=='T') return T; - else if (Output=='D') return d*MW; - else if (Output=='S') return s/MW; - else if (Output=='U') return e/MW; - else if (Output=='C') return cp/MW; - else if (Output=='O') return cv/MW; - else if (Output=='P') return p*1000; - else if (Output=='A') return w; - else if (Output=='V') - { - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return eta/1.0e6; //uPa-s to Pa-s - } - else if (Output=='L') - { - TRNPRPlib(T,d,x,eta,tcx,ierr,herr,errormessagelength); - return tcx/1000.0; //W/m-K to kW/m-K - } - else - return 1; - } - else - return 1; -} -// #endif diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp b/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp deleted file mode 100644 index 94d5262..0000000 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refprop_wrapper.org.cpp +++ /dev/null @@ -1,883 +0,0 @@ -/* - wrapper code for a static library containing functions from the dynamic - library librefprop.so to be used from Modelica - - This file is released under the Modelica License 2. - - Coded in 2010 by - Henning Francke - francke@gfz-potsdam.de - - Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences - Telegrafenberg, D-14473 Potsdam - - Modified for Linux in 2012 by - Jorrit Wronski (jowr@mek.dtu.dk) - DTU Mechanical Engineering - - needs - refprop.h - header for librefprop.so, based on examples - refprop_wrapper.h - header for REFPROP_wrapper.so, also needed by Dymola - - Use the provided makefile to install the library file from source. -*/ - -//#define DEBUGMODE 1 -// -//#include "Poco/SharedLibrary.h" -//using Poco::SharedLibrary; -// -//typedef void (*HelloFunc)(); // function pointer type -// -// -// -// -//typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double &); -// -////Define explicit function pointers -//fp_ABFL1dllTYPE ABFL1dll; -// -// -//int main(int argc, char** argv) -//{ -//std::string path("TestLibrary"); -//path.append(SharedLibrary::suffix()); // adds ".dll" or ".so" -//SharedLibrary library(path); // will also load the library -//HelloFunc func = (HelloFunc) library.getSymbol("hello"); -//func(); -//library.unload(); -//} -//return 0; - - - -#include -#if defined(WIN32) || defined(_WIN32) -# include -#else // assuming Linux system -# include -# include -# include // tolower etc -#endif -//# error "Could not determine system." -#include -#include "refprop_wrapper.h" - - -// Some constants... -const long filepathlength=1024; -const long errormessagelength=255+filepathlength; -const long lengthofreference=3; -const long refpropcharlength=255; -const long ncmax=20; // Note: ncmax is the max number of components - -//static const char RP_ -static char const GB_optId = '-' ; // - under UNIX -static char const GB_altOptId = '+' ; // + under UNIX -static char const GB_asciiEsc = '\\' ; // under UNIX -static char* const GB_preferredPathSep = "/" ; // / under UNIX -static char const GB_allowedPathSep[] = "/" ; -static bool const GB_ignoreCase = false ; // in filenames only. -static char const GB_stdinName[] = "-" ; -static int const GB_exitSuccess = 0 ; -static int const GB_exitWarning = 1 ; -static int const GB_exitError = 2 ; -static int const GB_exitFatal = 3 ; -static int const GB_exitInternal = 4 ; - - -char *str_replace(char *str, char *search, char *replace, long *count) { - int i,n_ret; - int newlen = strlen(replace); - int oldlen = strlen(search); - char *ret; - *count = 0; - - //count occurrences of searchstring - for (i = 0; oldlen && str[i]; ++i) - if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr - ++*count, i+=oldlen - 1; - } - ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); - if (!ret){ - printf("Could not allocate memory"); - return ""; - } - - if (!*count){ - strncpy(ret,str,n_ret); - //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); - }else{ - i = 0; - while (*str) - if (strstr(str, search) == str) - strncpy(&ret[i], replace,n_ret-i-1), - i += newlen, - str += oldlen; - else - ret[i++] = *str++; - ret[i] = '\0'; - } - return ret; -} - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, void* RefpropdllInstance, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP - char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - long ierr=0; - - if (strlen(REFPROP_PATH)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); - return 0; - } - - strcpy(FLD_PATH, REFPROP_PATH); - strcpy(DLL_PATH, REFPROP_PATH); - if (REFPROP_PATH[strlen(REFPROP_PATH)-1]==*GB_preferredPathSep){ //if last char is backslash -// strcat(DLL_PATH, "refprop.dll"); - strcat(FLD_PATH, "fluids"); - strcat(FLD_PATH, GB_preferredPathSep); - }else{//add missing backslash -// strcat(DLL_PATH,"\\refprop.dll"); - strcat(FLD_PATH, GB_preferredPathSep); - strcat(FLD_PATH, "fluids"); - strcat(FLD_PATH, GB_preferredPathSep); - } - - //std::string path("TestLibrary"); - //path.append(SharedLibrary::suffix()); // adds ".dll" or ".so" - //SharedLibrary library(path); // will also load the library - //HelloFunc func = (HelloFunc) library.getSymbol("hello"); - //func(); - //library.unload(); - - //*RefpropdllInstance = LoadLibrary(DLL_PATH); -// RefpropdllInstance = dlopen(DLL_PATH, RTLD_LAZY); -// if (!RefpropdllInstance){ -// sprintf(errormsg,"ERROR in opening librefprop.so at \"%s\"",DLL_PATH); -// fputs (dlerror(), stderr); -// return 100; -// } - - - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; - //char hf[refpropcharlength*ncmax]; - char *hf; - - - //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".FLD|"); - //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH,filepathlength-strlen(replace)); - - int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; - hf = (char*) calloc(hf_len, sizeof(char)); - - strncpy(hf,FLD_PATH,hf_len); - strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... - if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %i)\n",ncmax); - return 0; - } - strncat(hf,".FLD",hf_len-strlen(hf)); - if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); - - strncpy(hfmix,FLD_PATH,filepathlength+1);//add absolute path - strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); - strcpy(hrf,"DEF"); - - -// //...Call SETUP to initialize the program -// SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(*RefpropdllInstance,"SETUPdll"); -// //printf("hf:%s\n hrf: %s\n hfmix: %s\n",hf,hrf,hfmix); -// void (*SETUP)(void); -// void (*SETUP)(void); -// SETUP = dlsym(RefpropdllInstance, "SETUPdll"); -// if ((errormsg = dlerror()) != NULL) { -// fputs(errormsg, stderr); -// exit(1); -// } - - - if (DEBUGMODE) printf("Running SETUPdll...\n"); - SETUPdll(*nX, hf, hfmix, hrf, ierr, herr); - if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); - - -// if (DEBUGMODE) printf("Error code processing...\n"); - switch(ierr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening file %s",hf); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - strncpy(errormsg,herr,errormessagelength); - break; - } - free(hf); - return ierr; -} - - -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevars: string of any combination of two variables out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message -*/ - char statevars[3]; - double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; - long nX,ierr=0; //zero means no error - char herr[errormessagelength+1]; -// HINSTANCE RefpropdllInstance;// Then have windows load the library. - void* RefpropdllInstance; - - if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); - - //initialize interface to REFPROP.dll - - if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ - printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); - return 0; - } - - //CALCULATE MOLAR MASS -// WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); - WMOLdll(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - wm /= 1000; //g/mol -> kg/mol - - //identify and assign passed state variables - statevars[0] = tolower(statevars_in[0]); - statevars[1] = tolower(statevars_in[1]); - statevars[2] = '\0'; - if (statevars[0]!='\0'){ - if (statevars[0]==statevars[1]){ - props[0] = 3; - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); - return 0; - } - for (int ii=0;ii<2;ii++){ - val = (ii==0?statevar1:statevar2); - switch(statevars[ii]){ - case 'p': - p = val/1000; //Pa->kPa - break; - case 't': - T = val; - break; - case 's': - s = val*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = val*wm; //J/kg --> kJ/mol - break; - case 'd': - d = val/wm/1000; //kg/m� -> mol/dm� - break; - case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - q = val; - break; - default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ - return 0; - } - } - } - -/* -//...If phase j is known, call TPRHOdll: - long j=2; //phase definition(j=1: Liquid, j=2: Vapor) - long tmp_int=0; - TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); -*/ -//...If phase is not known, call TPFLSH - double xliq[ncmax],xvap[ncmax],f[ncmax]; - long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ -// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); - if (ierr==0){ - if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ -// strcat(errormsg,"Bin in TP!"); - if (phase==2){ //fluid state is known to be two phase -// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - }else{ -// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); - PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ -// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ - if (phase==1){ //fluid state is known to be single phase -// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); - }else{ -// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ -// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ -// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); - }else{*/ -// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ -// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ -// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); - long kr = 2; - TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ -// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ -// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s", statevars); - } - - switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE - case 'v': //dynamic viscosity uPa.s - case 'l': //thermal conductivity W/m.K -// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); - } - - - switch(ierr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 4: - sprintf(errormsg,"P=%f < 0",p); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",T,p); - break; - case 8: - strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); - break; - case 9: - sprintf(errormsg,"x or T=%f out of range",T); - break; - case 12: - sprintf(errormsg,"x out of range and P=%f < 0",p); - break; - case 13: - sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",d); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",d); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� - e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) - cv /= wm; - cp /= wm; - p *= 1000; //kPa->Pa - if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis - eta/=1e6; //uPa.s -> Pa.s - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e; //inner energy - props[9] = h; //specific enthalpy - props[10] = s;//specific entropy - props[11] = cv; - props[12] = cp; - props[13] = w; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii kg/mol - - if (DEBUGMODE) printf("\nwm converted.\n"); - - if (DEBUGMODE) printf("\statevar is %s \n",statevar_in); - //identify and assign passed state variables - // char tmpstr[1]; - // strcpy(tmpstr,statevar[0]); - // statevar = toLowerCase(tmpstr); - //statevar[0] = tolower(statevar[0]); - char statevar[1]; - statevar[0] = tolower(statevar_in[0]); - if (DEBUGMODE) printf("\nstatevar lowercase.\n"); - if (statevar[0]!='\0'){ -// if (strcmp(statevar[0],"")){ -// if (statevar[0] != NULL){ - if (DEBUGMODE) printf("\nentering statevar switch.\n"); - switch(statevar[0]){ - case 'p': - p = statevarval/1000; //Pa->kPa - break; - case 't': - T = statevarval; - break; - case 'd': - d = statevarval/wm/1000; //kg/m� -> mol/dm� - break; -/* case 's': - s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = statevarval*wm; //J/kg --> kJ/mol - break; -*/ default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable: %c", statevarval); - return 0; - } - } - - if (DEBUGMODE) printf("\nstatevar checked.\n"); - - double xliq[ncmax],xvap[ncmax],f[ncmax]; - - long j=2,kr; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - if (ierr==0) - if (~strcmp(statevar,"t")){ -// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - }else if (~strcmp(statevar,"p")){ -// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - }else if (~strcmp(statevar,"d")){ -// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - - switch(ierr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 8: - strcpy(errormsg,"x out of range"); - break; - case 9: - strcpy(errormsg,"T and x out of range"); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); - SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); - SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� -/* e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) -*/ p *= 1000; //kPa->Pa - } - - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in kPa->Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii -#if defined(WIN32) || defined(_WIN32) -# include -//# include "REFPROP_dll.h" -#else // assuming Linux system -# include -# include -//# include // dlopen etc -# include // tolower etc -#endif -#include -//# error "Could not determine system." -#include "refprop_wrapper.h" - -// get the POCO classes -#include "Poco/SharedLibrary.h" -#include "Poco/Path.h" -#include "Poco/File.h" -#include "Poco/Environment.h" -#include "Poco/StringTokenizer.h" -#include "Poco/String.h" -#include "Poco/Exception.h" - - -// Some constants... -const long maxstringlength=10000; -const long filepathlength=1024; -const long errormessagelength=255+filepathlength; -const long lengthofreference=3; -const long refpropcharlength=255; -const long ncmax=20; // Note: ncmax is the max number of components - -Poco::SharedLibrary *RefpropdllInstance = NULL; -char loadedfluids[refpropcharlength]; -char loadedpath[filepathlength]; - -// Define the functions either by their pointers or type. -WMOLdll_POINTER WMOL = NULL; -TPFL2dll_POINTER TPFL2 = NULL; -TPFLSHdll_POINTER TPFLSH = NULL; -PHFL1dll_POINTER PHFL1 = NULL; -PHFLSHdll_POINTER PHFLSH = NULL; -PDFL1dll_POINTER PDFL1 = NULL; -PDFLSHdll_POINTER PDFLSH = NULL; -PSFLSHdll_POINTER PSFLSH = NULL; -PQFLSHdll_POINTER PQFLSH = NULL; -THFLSHdll_POINTER THFLSH = NULL; -TDFLSHdll_POINTER TDFLSH = NULL; -TSFLSHdll_POINTER TSFLSH = NULL; -TQFLSHdll_POINTER TQFLSH = NULL; -DHFL1dll_POINTER DHFL1 = NULL; -DHFL2dll_POINTER DHFL2 = NULL; -DHFLSHdll_POINTER DHFLSH = NULL; -HSFLSHdll_POINTER HSFLSH = NULL; -DSFL1dll_POINTER DSFL1 = NULL; -DSFL2dll_POINTER DSFL2 = NULL; -DSFLSHdll_POINTER DSFLSH = NULL; -TRNPRPdll_POINTER TRNPRP = NULL; -SATTdll_POINTER SATT = NULL; -SATPdll_POINTER SATP = NULL; -SATDdll_POINTER SATD = NULL; - -// char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { -// int i,n_ret; -// int newlen = strlen(replace); -// int oldlen = strlen(search); -// char *ret; -// *count = 0; -// -// //count occurrences of searchstring -// for (i = 0; oldlen && str[i]; ++i) -// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr -// ++*count, i+=oldlen - 1; -// } -// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); -// if (!ret){ -// printf("Could not allocate memory"); -// return ""; -// } -// -// if (!*count){ -// strncpy(ret,str,n_ret); -// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); -// }else{ -// i = 0; -// while (*str) -// if (strstr(str, search) == str) -// strncpy(&ret[i], replace,n_ret-i-1), -// i += newlen, -// str += oldlen; -// else -// ret[i++] = *str++; -// ret[i] = '\0'; -// } -// return ret; -// } - -//str_replace (fluidnames, "|", replace, nX) -char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { - - *count = 0; - char ret[maxstringlength]; - - std::string fluids(str); - std::string dlimit(search); - std::string substi(replace); - std::string result; - - // if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); - // if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); - // if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); - // if (DEBUGMODE) printf("nX: %li\n\n",*count); - - Poco::StringTokenizer tokens(fluids.c_str(), dlimit.c_str(), Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); - result = std::string(Poco::cat(substi, tokens.begin(), tokens.end())); - - strcpy(ret,result.c_str()); - //strcat(ret,'\0'); - - *count = tokens.count()-1; - - if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); - if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); - if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); - if (DEBUGMODE) printf("replaced: %s\n",result.c_str()); - if (DEBUGMODE) printf("nX: %li\n\n",*count); - -return ret; - -} - -// char printDoubleArray (double* arr[] ) { -// std::copy(arr.begin(),arr.end(),std::ostream_iterator(std::cout,", ")); -// } - -char *printX(double arr[], long nX) { - char ret[filepathlength]; - char tmp[filepathlength]; - strcpy(ret,"("); - //for(int i = 0; i < (sizeof(arr)-1); i++) { - for(int i = 0; i < (nX-2); i++) { - sprintf(tmp,"%f, ", arr[i]); - strcat(ret,tmp); - } - sprintf(tmp,"%f", arr[nX-1]); - strcat(ret,tmp); - - strcat(ret,")"); - //printf ("output: %s \n", ret); - return ret; -} - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP -// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - - long ierr=0; -// DEBUGMODE = 1; - - if (strlen(REFPROP_PATH_CHAR)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %li)\n",strlen(REFPROP_PATH_CHAR),filepathlength); - return 0; - } - // Define temporary objects for checks. - char REF_PATH_CHAR[filepathlength]; - Poco::Path REF_PATH(true); - char FLUIDS_CHAR[filepathlength] = "fluids"; - Poco::Path FLD_PATH(true); - char LIBRARY_CHAR[filepathlength]; - Poco::Path LIB_PATH(true); - //Poco::File theFile; - - // Parse the string and append a path separator if necessary. - REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); - if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); - // Overwrite the provided path - strcpy(REF_PATH_CHAR,REF_PATH.toString().c_str()); - - // Check the path if running in debugmode - if (DEBUGMODE) { - Poco::File refFile(REF_PATH); - if ( !refFile.isDirectory() || !refFile.canRead() ){ - printf ("REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - return 0; - } else { - printf ("REF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); - } - } - - // The fluid files are in the Refprop directory, append "fluids". - FLD_PATH.parse(REF_PATH_CHAR); - FLD_PATH.pushDirectory(FLUIDS_CHAR); - -// //std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... -// Poco::Path SRC_PATH; -// SRC_PATH.parse(Poco::Environment::get("PATH")); - -// if (DEBUGMODE) { -// // Determine which library file should be loaded -// bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); -// if (is_linux){ -// strcpy(LIBRARY_CHAR,"librefprop.so"); -// SRC_PATH.pushDirectory("/usr/local/lib"); -// } else { -// strcpy(LIBRARY_CHAR,"refprop.dll"); -// SRC_PATH.pushDirectory(REF_PATH.toString()); -// } - - - //bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); -// if (found_lib) { -// printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); -// } else { -// printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); -// } -// } else { -// LIB_PATH.parse(REF_PATH_CHAR); -// } - - //LIB_PATH.parse(LIBRARY_CHAR); - -// if (DEBUGMODE) { -// printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); -// printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); -// printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); -// printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); -// } - - Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... - - if (RefpropdllInstance==NULL) { // we need to load the library - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); - - // Check the OS and assign the right names for the library - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - strcpy(LIBRARY_CHAR,"librefprop.so"); - SRC_PATH.parse("/usr/local/lib"); - } else { - strcpy(LIBRARY_CHAR,"refprop.dll"); - SRC_PATH = REF_PATH; - } - - // search the library at the given path - bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); - if (found_lib) { - if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - } else { - if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - return 0; - } - - // check if the file is correct and executable - if (DEBUGMODE) { - Poco::File libFile(LIB_PATH); - if ( !libFile.isFile() || !libFile.canRead() ){ - printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - sprintf (errormsg,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - return 0; - } else { - printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); - } - } - - // load a new library instance - RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); - - } else { // library was already loaded - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); - } - - // Now the library is loaded and we can start checkicng the fluid path - if (DEBUGMODE) { - Poco::File fldFile(FLD_PATH); - if ( !fldFile.isDirectory() || !fldFile.canRead() ){ - printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return 0; - } else { - printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); - } - } - char FLD_PATH_CHAR[filepathlength]; - strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - - - if (DEBUGMODE) { - printf ("%s\n"," "); - printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); - printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); - printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); - printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); - printf ("%s\n"," "); - } - - - // Check for new fluids and if the library has to be loaded again. - bool isFluid = (strcmp(fluidnames,loadedfluids)==0); - bool isPath = (strcmp(REF_PATH_CHAR,loadedpath)==0); - if (DEBUGMODE) printf ("Comparison of fluids : %i \n", isFluid ); - if (DEBUGMODE) printf ("Comparison of path : %i \n\n", isPath ); - //if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); - - char *hf; - -// // // // if (isFluid && isPath) { -// // // // //sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); -// // // // if (DEBUGMODE) printf ("No setup needed, fluids (%s) and path (%s) did not change.\n\n", fluidnames,REF_PATH_CHAR); -// // // // // // // // return 0; -// // // // } else { - // we need to call setup - - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; -// // // // char *hf; - - //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".FLD|"); - //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); - - //int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; - int hf_len = maxstringlength; - hf = (char*) calloc(hf_len, sizeof(char)); - - strncpy(hf,FLD_PATH_CHAR,hf_len); - - char replaced[filepathlength]; - - strcpy(replaced,str_replace(fluidnames, "|", replace, nX, DEBUGMODE)); - - //str_replace returns the number of delimiters -> nX, but components are one more ... - if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %li)\n",ncmax); - return 0; - } - - - strncat(hf,replaced,hf_len-strlen(hf)); - - strncat(hf,".FLD",hf_len-strlen(hf)); - - if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); - - strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path - strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); - strcpy(hrf,"DEF"); - - - SETUPdll_POINTER SETUP = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); - if (DEBUGMODE) printf("Running SETUP...\n"); - //char hftmp[maxstringlength]; - //strcpy(hftmp,hf); - static char hfld[maxstringlength+1]; - strcpy(hfld,hf); - SETUP(*nX, hfld, hfmix, hrf, ierr, herr); - - strcpy(loadedfluids,fluidnames); - strcpy(loadedpath,REF_PATH_CHAR); - if (DEBUGMODE) printf("SETUP run complete (Error no: %li)\n",ierr); - - if (DEBUGMODE) printf("Error code processing...\n"); - switch(ierr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening file %s",hf); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - strncpy(errormsg,herr,errormessagelength); - break; - } -// // // // free(hf); - return ierr; - - -// if (DEBUGMODE) { -// theFile = Poco::File(LIB_PATH); -// if ( !theFile.isFile() || !theFile.canExecute() ){ -// sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); -// return 0; -// } -// } -// char LIB_PATH_CHAR[filepathlength]; -// strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); -// -// if (DEBUGMODE) { -// theFile = Poco::File(FLD_PATH); -// if ( !theFile.isDirectory() || !theFile.canRead() ){ -// sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); -// return 0; -// } -// } -// char FLD_PATH_CHAR[filepathlength]; -// strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - -//// First we load the library with the POCO foundation -//// classes and then define all the needed functions -//// by their names and a cast to the correct type. -// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); -// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); -// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); -// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { -// RefpropdllInstance.unload(); -// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); -// RefpropdllInstance.load(LIB_PATH_CHAR); -// } -// -// if (!RefpropdllInstance.isLoaded()){ -// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); -// return 100; -// } - - -// char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; -// char *hf; -// -// //parse fluid composition string and insert absolute paths -// char replace[filepathlength+6]; -// strcpy(replace,".FLD|"); -// //if (DEBUGMODE) printf("REPLACE: %s\n",replace); -// strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); -// -// int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; -// hf = (char*) calloc(hf_len, sizeof(char)); -// -// strncpy(hf,FLD_PATH_CHAR,hf_len); -// strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... -// if (++*nX>ncmax){ //...that's why nX is incremented -// sprintf(errormsg,"Too many components (More than %i)\n",ncmax); -// return 0; -// } -// strncat(hf,".FLD",hf_len-strlen(hf)); -// if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); -// -// strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path -// strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); -// strcpy(hrf,"DEF"); -// -// -// // SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); -// if (DEBUGMODE) printf("Running SETUPdll...\n"); -// SETUP(*nX, hf, hfmix, hrf, ierr, herr); -// strcpy(loadedfluids,fluidnames); -// if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); -// -// // WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); -// // TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); -// // TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); -// // PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); -// // PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); -// // PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); -// // PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); -// // PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); -// // PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); -// // THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); -// // TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); -// // TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); -// // TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); -// // DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); -// // DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); -// // DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); -// // HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); -// // DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); -// // DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); -// // DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); -// // TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); -// // SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); -// // SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); -// // SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); - - -// // if (DEBUGMODE) printf("Error code processing...\n"); -// switch(ierr){ -// case 101: -// //strcpy(errormsg,"error in opening file"); -// // if (DEBUGMODE) printf("Error 101\n"); -// sprintf(errormsg,"error in opening file %s",hf); -// break; -// case 102: -// // if (DEBUGMODE) printf("Error 102\n"); -// strcpy(errormsg,"error in file or premature end of file"); -// break; -// case -103: -// // if (DEBUGMODE) printf("Error -103\n"); -// strcpy(errormsg,"unknown model encountered in file"); -// break; -// case 104: -// // if (DEBUGMODE) printf("Error 104\n"); -// strcpy(errormsg,"error in setup of model"); -// break; -// case 105: -// // if (DEBUGMODE) printf("Error 105\n"); -// strcpy(errormsg,"specified model not found"); -// break; -// case 111: -// // if (DEBUGMODE) printf("Error 111\n"); -// strcpy(errormsg,"error in opening mixture file"); -// break; -// case 112: -// // if (DEBUGMODE) printf("Error 112\n"); -// strcpy(errormsg,"mixture file of wrong type"); -// break; -// case 114: -// // if (DEBUGMODE) printf("Error 114\n"); -// strcpy(errormsg,"nc<>nc from setmod"); -// break; -// case 0: -// break; -// default: -// // if (DEBUGMODE) printf("Unknown error\n"); -// strcpy(errormsg,"Unknown error"); -// //strcpy(errormsg,"Setup was successful!"); -// strncpy(errormsg,herr,errormessagelength); -// break; -// } -// free(hf); -// return ierr; -} - - -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevars: string of any combination of two variables out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message -*/ - char statevars[3]; - double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; - long nX,ierr=0; //zero means no error - char herr[errormessagelength+1]; -// HINSTANCE RefpropdllInstance;// Then have windows load the library. -// Poco::SharedLibrary RefpropdllInstance(""); - -// DEBUGMODE = 1; - - if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); - - //initialize interface to REFPROP.dll -// if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ -// printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); -// return 0; -// } - if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ - printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); - return 0; - } - - //CALCULATE MOLAR MASS -// WMOL = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); -// WMOLdll_TYPE * WMOL = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); - WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); - WMOL(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - wm /= 1000; //g/mol -> kg/mol - - //identify and assign passed state variables - statevars[0] = tolower(statevars_in[0]); - statevars[1] = tolower(statevars_in[1]); - statevars[2] = '\0'; - if (statevars[0]!='\0'){ - if (statevars[0]==statevars[1]){ - props[0] = 3; - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); - return 0; - } - for (int ii=0;ii<2;ii++){ - val = (ii==0?statevar1:statevar2); - switch(statevars[ii]){ - case 'p': - p = val/1000; //Pa->kPa - break; - case 't': - T = val; - break; - case 's': - s = val*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = val*wm; //J/kg --> kJ/mol - break; - case 'd': - d = val/wm/1000; //kg/m� -> mol/dm� - break; - case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - q = val; - break; - default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ - return 0; - } - } - } - -/* -//...If phase j is known, call TPRHO: - long j=2; //phase definition(j=1: Liquid, j=2: Vapor) - long tmp_int=0; - TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHO(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); -*/ -//...If phase is not known, call TPFLSH - double xliq[ncmax],xvap[ncmax],f[ncmax]; - long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ -// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); - if (ierr==0){ - if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ -// strcat(errormsg,"Bin in TP!"); - if (phase==2){ //fluid state is known to be two phase -// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2 = (TPFL2dll_POINTER) RefpropdllInstance->getSymbol(TPFL2dll_NAME); - TPFL2(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - }else{ -// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSH = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); - TPFLSH(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -// if (phase==1){ //fluid state is known to be single phase -//// PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); -// PHFL1 = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); -// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); -//// if (liqvap==1) dl=d; else dv=d; -// }else{ -//// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSH = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); - PHFLSH(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ - if (phase==1){ //fluid state is known to be single phase -// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1 = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); - PDFL1(p,d,x,T,ierr,herr,errormessagelength); - }else{ -// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSH = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); - PDFLSH(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1(p,s,x,kph,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ -// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSH = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); - PSFLSH(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ -// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSH = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); - PQFLSH(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); - }else{*/ -// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); - THFLSH = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSH (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ -// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSH = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); - TDFLSH(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ -// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); - TSFLSH = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); - long kr = 2; - TSFLSH(T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ -// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSH = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); - TQFLSH(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); - DHFL1(d,h,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2 = (DHFL2dll_POINTER) RefpropdllInstance->getSymbol(DHFL2dll_NAME); - DHFL2(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSH = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); - DHFLSH(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - break; - } - }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ -// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSH = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); - HSFLSH(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1 = (DSFL1dll_POINTER) RefpropdllInstance->getSymbol(DSFL1dll_NAME); - DSFL1(d,s,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2 = (DSFL2dll_POINTER) RefpropdllInstance->getSymbol(DSFL2dll_NAME); - DSFL2(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSH = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); - DSFLSH(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - break; - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s", statevars); - } - - switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE - case 'v': //dynamic viscosity uPa.s - case 'l': //thermal conductivity W/m.K -// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRP = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); - TRNPRP(T,d,x,eta,tcx,ierr,herr,errormessagelength); - break; - } - - - switch(ierr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 4: - sprintf(errormsg,"P=%f < 0",p); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",T,p); - break; - case 8: - sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(x,nX)); - break; - case 9: - sprintf(errormsg,"x=%s or T=%f out of range",printX(x,nX),T); - break; - case 12: - sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(x,nX),p); - break; - case 13: - sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(x,nX),T,p); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",d); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",d); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - break; - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); - break; - default: - strncpy(errormsg,herr,errormessagelength); - break; - } - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOL(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOL(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� - e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) - cv /= wm; - cp /= wm; - p *= 1000; //kPa->Pa - if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis - eta/=1e6; //uPa.s -> Pa.s - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e; //inner energy - props[9] = h; //specific enthalpy - props[10] = s;//specific entropy - props[11] = cv; - props[12] = cp; - props[13] = w; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;iigetSymbol(WMOLdll_NAME); - WMOL(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); - - wm /= 1000; //g/mol -> kg/mol - - if (DEBUGMODE) printf("wm converted.\n"); - - if (DEBUGMODE) printf("statevar is %s \n",statevar_in); - //identify and assign passed state variables - // char tmpstr[1]; - // strcpy(tmpstr,statevar[0]); - // statevar = toLowerCase(tmpstr); - //statevar[0] = tolower(statevar[0]); - char statevar[1]; - statevar[0] = tolower(statevar_in[0]); - if (DEBUGMODE) printf("\nstatevar lowercase.\n"); - if (statevar[0]!='\0'){ -// if (strcmp(statevar[0],"")){ -// if (statevar[0] != NULL){ - if (DEBUGMODE) printf("\nentering statevar switch.\n"); - switch(statevar[0]){ - case 'p': - p = statevarval/1000; //Pa->kPa - break; - case 't': - T = statevarval; - break; - case 'd': - d = statevarval/wm/1000; //kg/m� -> mol/dm� - break; -/* case 's': - s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = statevarval*wm; //J/kg --> kJ/mol - break; -*/ default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable: %f", statevarval); - return 0; - } - } - - if (DEBUGMODE) printf("\nstatevar checked.\n"); - - double xliq[ncmax],xvap[ncmax],f[ncmax]; - - long j=2,kr; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - if (ierr==0) { - if (~strcmp(statevar,"t")){ -// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATT = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); - SATT(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - }else if (~strcmp(statevar,"p")){ -// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATP = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); - SATP(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - }else if (~strcmp(statevar,"d")){ -// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATD = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); - SATD(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - } - - switch(ierr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 8: - sprintf(errormsg,"x out of range, %s",printX(x,nX)); - break; - case 9: - sprintf(errormsg,"T=%f and x=%s out of range",T,printX(x,nX)); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - strncpy(errormsg,herr,errormessagelength); - break; - } - - /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); - SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); - SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOL(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOL(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� -/* e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) -*/ p *= 1000; //kPa->Pa - } - - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in kPa->Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii +#endif + +#include +#include +#include +#include +#include +#include +#include // tolower, toupper, etc + +#include +//#include +//#include +//#include +//#include + +#include "refprop_wrapper.h" + +// get the POCO classes +#include "Poco/SharedLibrary.h" +#include "Poco/Path.h" +#include "Poco/File.h" +#include "Poco/Environment.h" +#include "Poco/String.h" +#include "Poco/NumberFormatter.h" +#include "Poco/StringTokenizer.h" +#include "Poco/Exception.h" + + +// Define the functions either by their pointers or type. +WMOLdll_POINTER WMOLlib = NULL; +TPFL2dll_POINTER TPFL2lib = NULL; +TPFLSHdll_POINTER TPFLSHlib = NULL; +PHFL1dll_POINTER PHFL1lib = NULL; +PHFLSHdll_POINTER PHFLSHlib = NULL; +PDFL1dll_POINTER PDFL1lib = NULL; +PDFLSHdll_POINTER PDFLSHlib = NULL; +PSFLSHdll_POINTER PSFLSHlib = NULL; +PQFLSHdll_POINTER PQFLSHlib = NULL; +THFLSHdll_POINTER THFLSHlib = NULL; +TDFLSHdll_POINTER TDFLSHlib = NULL; +TSFLSHdll_POINTER TSFLSHlib = NULL; +TQFLSHdll_POINTER TQFLSHlib = NULL; +DHFL1dll_POINTER DHFL1lib = NULL; +DHFL2dll_POINTER DHFL2lib = NULL; +DHFLSHdll_POINTER DHFLSHlib = NULL; +HSFLSHdll_POINTER HSFLSHlib = NULL; +DSFL1dll_POINTER DSFL1lib = NULL; +DSFL2dll_POINTER DSFL2lib = NULL; +DSFLSHdll_POINTER DSFLSHlib = NULL; +TRNPRPdll_POINTER TRNPRPlib = NULL; +SATTdll_POINTER SATTlib = NULL; +SATPdll_POINTER SATPlib = NULL; +SATDdll_POINTER SATDlib = NULL; +SETUPdll_POINTER SETUPlib = NULL; +XMASSdll_POINTER XMASSlib = NULL; +XMOLEdll_POINTER XMOLElib = NULL; + + +/* + * Just a helper function control the output of + * an array. Used to debug the handling of the + * composition arrays. + */ +std::string printX(double arr[], long nc) { + std::string ret = "("; + int stop = nc-1; + + for(int i = 0; i < (stop); i++) { + ret = ret + Poco::NumberFormatter::format(arr[i], 4) + ", "; // four decimals + } + + ret = ret + Poco::NumberFormatter::format(arr[stop], 4) + ")"; // four decimals + return ret; +} + + + + + + + + + + + + + + + + + + + + + +/* + * Define pointer to library as well as the + * strings we need to determine whether a + * call to SETUPlib is needed. + */ +Poco::SharedLibrary *RefpropdllInstance = NULL; +std::string loadedFluids; + + +/* + * Here we define the fluid's properties. These values get updated after each + * call to Refprop and are used for caching values. I decided to use the + * Refprop units for internal data storage Be careful when converting + * properties using the molecular weight. It is stored in g/mol. + */ + long kq = 2; // all qualities are calculated on a mass basis +static const double noValue = -1e+10; + +static const std::string FLUIDS_PATH = "fluids"; +static const std::string LIN_LIBRARY = "librefprop.so"; +static const std::string WIN_LIBRARY = "refprop.dll"; +Poco::Path FLD_PATH(true); + + +// static const double noFactor = 1e+0; +// static const double presFactor = 1e+3; +// static const double viscFactor = 1e+6; +// static const double molwFactor = 1e-3; +// double energyFactor = noValue; // J/mol / g/mol * 1000g/kg = J/kg +// double densityFactor[3] = {noValue}; // mol/l * g/mol = g/l = kg/m3 for all phases +// double fractionFactor[ncmax] = {noValue}; // xkgi = xmi * mwi * mw (array) +// double qualityFactor = noValue; // qmass = qmole * mw_vap / mw + +bool debug; // set the debug flag +//long lerr; // Error return mechanism +double dhelp = noValue; +double delta = 1e-12; // tolerance for evaluating differences + + +/* + * Properties for saturation states. "dew" refers to the dew point and + * "bub" describes the bubble point. + */ +double dtdew, dpdew, ddldew, ddvdew, dtbub, dpbub, ddlbub, ddvbub; +int flushSaturation() { + dtdew=noValue; + dpdew=noValue; + ddldew=noValue; + ddvdew=noValue; + dtbub=noValue; + dpbub=noValue; + ddlbub=noValue; + ddvbub=noValue; + if (debug) printf ("Finished flushing saturation properties.\n"); + return 0; +} + + +/* + * Most of the fluid properties are stored here. There are arrays for + * composition information as well as single values for the other + * properties. + * The flush function gets called when the state changes and the + * previously calculated are not valid anymore. A change of state also leads + * to changed saturation conditions. + */ +double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, + ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, + dhjt, dZ, dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, + ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn; +int flushProperties(){ + dt=noValue; + dp=noValue; + de=noValue; + dh=noValue; + ds=noValue; + dqmol=noValue; + dd=noValue; + dxmol[ncmax]=noValue; + ddl=noValue; + ddv=noValue; + dxmoll[ncmax]=noValue; + dxmolv[ncmax]=noValue; + dCv=noValue; + dCp=noValue; + dw=noValue; + dwliq=noValue; + dwvap=noValue; + dhjt=noValue; + dZ=noValue; + dA=noValue; + dG=noValue; + dxkappa=noValue; + dbeta=noValue; + ddpdd=noValue; + dd2pdd2=noValue; + ddpdt=noValue; + ddddt=noValue; + ddddp=noValue; + dd2pdt2=noValue; + dd2pdtd=noValue; + ddhdt=noValue; + df=noValue; + deta=noValue; + dtcx=noValue; + dstn=noValue; + if (debug) printf ("Finished flushing normal fluid properties.\n"); + return flushSaturation(); +} + + +/* + * Properties that are constants for pure fluids. Hence, the flushing + * function gets called when a new fluid is loaded. In case of a mixture, + * a change of composition also triggers a flushing since this also + * changes those that also exist for mixtures. + * A change of composition or fluid always leads to a flushing of the + * other properties. + */ +long lnc; // number of components +double dwm, dttp, dtnbp, dtc, dpc, ddc, dZc, dacf, ddip, drgas; +int flushConstants() { + //lnc = -1; + dwm = noValue; + dttp = noValue; + dtnbp = noValue; + dtc = noValue; + dpc = noValue; + ddc = noValue; + dZc = noValue; + dacf = noValue; + ddip = noValue; + drgas = noValue; + if (debug) printf ("Finished flushing fluid/mixture \"constants\".\n"); + return flushProperties(); +} + + +/* + * Make sure that the library is loaded and that all the functions have + * pointers. Perform detailed checks if the debug flag is set. This is + * could be set from inside Modelica to find out why there are problems + * with loading the Refprop library. It is assumed that the library + * file lies in the same directory as the fluid folder. + */ +int setPaths(std::string pathToRefprop, Poco::Path* LP, char* error) { + + if (debug) printf ("\nSetting paths\n"); + + if (pathToRefprop.length()>filepathlength){ + sprintf(error,"Path too long (%i > %i)\n",pathToRefprop.length(),filepathlength); + return -1; + } + + // Parse the string and append a path separator if necessary. + Poco::Path REF_PATH; + REF_PATH.parse(pathToRefprop, Poco::Path::PATH_NATIVE); + if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); + // Check the path if running in debug mode + if (debug) { + Poco::File refFile(REF_PATH); + if ( !refFile.isDirectory() || !refFile.canRead() ){ + printf ("The provided library path is not a readable directory: %s \n", REF_PATH.toString().c_str()); + sprintf (error,"The provided library path is not a readable directory: %s \n", REF_PATH.toString().c_str()); + return -1; + } else { + printf ("The provided library path is a readable directory: %s \n", REF_PATH.toString().c_str()); + } + } + + // Poco::Path FLD_PATH = (*FP); // get the object + // The fluid files are in the Refprop directory, append "fluids". + FLD_PATH.parse(REF_PATH.toString()); + FLD_PATH.pushDirectory(FLUIDS_PATH); + // Check the path if running in debug mode + if (debug) { + Poco::File fluidFile(FLD_PATH); + if ( !fluidFile.isDirectory() || !fluidFile.canRead() ){ + printf ("The provided fluid path is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + sprintf (error,"The provided fluid path is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + return -1; + } else { + printf ("The provided fluid path is a readable directory: %s \n", FLD_PATH.toString().c_str()); + } + } + + Poco::Path SRC_PATH; // We might want to define the search path differently + bool found_lib; + + // Check the OS and assign the right names for the library + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + //SRC_PATH.parse("/usr/local/lib"); + SRC_PATH = REF_PATH; + found_lib = Poco::Path::find(SRC_PATH.toString(), LIN_LIBRARY, (*LP)); + } else { + SRC_PATH = REF_PATH; + found_lib = Poco::Path::find(SRC_PATH.toString(), WIN_LIBRARY, (*LP)); + } + + if (found_lib) { + if (debug) printf ("Found library at %s \n", LP->toString().c_str()); + } else { + if (debug) printf ("Cannot find library in path %s \n", SRC_PATH.toString().c_str()); + sprintf (error,"Cannot find library in path %s \n", SRC_PATH.toString().c_str()); + return -1; + } + + // Check the file if running in debug mode + if (debug) { + Poco::File libFile(LP); + if ( !libFile.canRead() ){ + printf ("The provided library is not a readable file: %s \n", LP->toString().c_str()); + sprintf (error,"The provided library is not a readable file: %s \n", LP->toString().c_str()); + return -1; + } else { + printf ("The provided library is a readable file: %s \n", LP->toString().c_str()); + } + } + + return 0; +} + + + +int loadLibrary(std::string pathToRefprop, char* error) { + + if (debug) printf ("\nLoading library.\n"); + + if (RefpropdllInstance==NULL) { + + long lerr = 0; + + if (debug) printf ("Library is not loaded, trying to do so.\n"); + Poco::Path LIB_PATH(true); + + // use the function to set the global path to fluids and + // get the path to the library to load + lerr = setPaths(pathToRefprop, &LIB_PATH, error); + if (lerr!=0) { + printf ("\nThere was an error setting the paths. This hint \n"); + printf ("might help: %s \n", error); + return lerr; + } + + // load a new library instance + if (debug) printf ("Loaded library at: %s \n",LIB_PATH.toString().c_str()); + + RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); + if (RefpropdllInstance==NULL) { + printf("Could not load Refprop library, but no error message was provided.\n"); + return -1; + } + + // Get pointers to functions from library. + DHFLSHlib = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); + DSFLSHlib = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); + HSFLSHlib = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); + PDFL1lib = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); + PDFLSHlib = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); + PHFL1lib = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); + PHFLSHlib = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); + PQFLSHlib = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); + PSFLSHlib = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); + SATDlib = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); + SATPlib = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); + SATTlib = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); + TDFLSHlib = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); + THFLSHlib = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); + TPFLSHlib = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); + TQFLSHlib = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); + TRNPRPlib = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); + TSFLSHlib = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); + WMOLlib = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); + XMASSlib = (XMASSdll_POINTER) RefpropdllInstance->getSymbol(XMASSdll_NAME); + XMOLElib = (XMOLEdll_POINTER) RefpropdllInstance->getSymbol(XMOLEdll_NAME); + SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); + // + if (debug) printf ("Library instance successfully loaded.\n"); + } else { // library was already loaded + if (debug) printf ("Library instance already, not doing anything.\n"); + } + return 0; +} + + +/* + * Processes the provided strings and constructs a fluid definition string + * that can be digested by the Refprop library. + */ +int setFluid(std::string fluid, char* error){ + + if (debug) printf ("\nSetting fluids\n"); + + char hf[refpropcharlong]; + char hfmix[refpropcharlong]; + char hrf[lengthofreference+1]; + std::string RefString; + long lerr; + + // If the name of the fluid doesn't match that of the currently loaded fluid + if (debug) printf("Loaded fluids: %s \n",loadedFluids.c_str()); + if (debug) printf("New fluids: %s \n",fluid.c_str()); + if (loadedFluids.compare(fluid)) { // There is a mismath + if (debug) printf("Loading a new fluid.\n"); + if (fluid.find("|") != std::string::npos) { // check if contains mixture separator + // Created string to insert into parsed fluids + std::string replace = std::string(".FLD|") + FLD_PATH.toString(); + // Prepare final string for values and get tokens + RefString = FLD_PATH.toString(); + Poco::StringTokenizer tokens(std::string(fluid), "|", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); + RefString += Poco::cat(replace, tokens.begin(), tokens.end()); + RefString += std::string(".FLD"); + lnc = tokens.count(); + if (lnc>ncmax){ + sprintf(error,"Too many components (More than %i)\n",ncmax); + return -1; + } + } + else if (!fluid.compare("Air") || !fluid.compare("R507A") || !fluid.compare("R404A") || !fluid.compare("R410A") || !fluid.compare("R407C") || !fluid.compare("SES36")) + { + lnc=1; + RefString = FLD_PATH.toString() + fluid + std::string(".PPF"); + dxmol[0]=1.0; //Pseudo-Pure fluid + } + else + { + lnc=1; + RefString = FLD_PATH.toString() + fluid + std::string(".FLD"); + dxmol[0]=1.0; //Pure fluid + } + + if (debug) printf("RefString: %s \n",RefString.c_str()); + strcpy(hf,RefString.c_str()); + strcpy(hfmix,FLD_PATH.toString().c_str()); + strcat(hfmix,"HMX.BNC"); + strcpy(hrf,"DEF"); + strcpy(error,"Ok"); + + //...Call SETUPlib to set the fluids + if (debug) { + printf("Running SETUP...\n"); + printf ("No. of components: %li \n", lnc); + printf ("Fluid files: %s \n", RefString.c_str()); + printf ("Mixture file: %s \n", hfmix); + } + + lerr=999; + SETUPlib(lnc, hf, hfmix, hrf, lerr, error); + if (lerr != 0) { + printf("REFPROP setup gives this error during SETUP: %s\n",error); + return lerr; + } + + //Copy the name of the loaded refrigerant back into the temporary holder + loadedFluids = std::string(fluid); + + int flush = flushConstants(); + if (debug) printf("Loading a new fluid, flushing constants: %i.\n",flush); + } else { + if (debug) printf("Fluid was already loaded.\n"); + } + return 0; +} + + +int init_REFPROP(std::string fluidnames, std::string REFPROP_PATH_CHAR, char* errormsg){ +// Sets up the interface to the REFPROP.DLL +// is called by props_REFPROP and satprops_REFPROP +// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; + + long lerr = 0; + //ierr=0; +// debug = true; + + if (debug) printf ("\nInitialising library\n"); + + lerr = loadLibrary(REFPROP_PATH_CHAR, errormsg); + if (lerr!=0) { + printf ("There was an error loading the library. This hint \n"); + printf ("might help: %s \n", errormsg); + } + +// if (debug) { +// printf ("%s\n"," "); +// printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); +// printf ("Loaded library : %li \n", lerr); +// printf ("Fluids are located: %s \n", FLD_PATH.toString().c_str()); +// //printf ("%s\n"," "); +// } + + lerr = setFluid(fluidnames, errormsg); + if (lerr!=0) { + printf ("There was an error loading the fluids. This hint \n"); + printf ("might help: %s \n", errormsg); + } + + if (debug) printf("Error code processing...\n"); + switch(lerr){ + case 101: + //strcpy(errormsg,"error in opening file"); +// if (DEBUGMODE) printf("Error 101\n"); + sprintf(errormsg,"error in opening fluid file"); + break; + case 102: +// if (DEBUGMODE) printf("Error 102\n"); + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: +// if (DEBUGMODE) printf("Error -103\n"); + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: +// if (DEBUGMODE) printf("Error 104\n"); + strcpy(errormsg,"error in setup of model"); + break; + case 105: +// if (DEBUGMODE) printf("Error 105\n"); + strcpy(errormsg,"specified model not found"); + break; + case 111: +// if (DEBUGMODE) printf("Error 111\n"); + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: +// if (DEBUGMODE) printf("Error 112\n"); + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: +// if (DEBUGMODE) printf("Error 114\n"); + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 0: + break; + default: +// if (DEBUGMODE) printf("Unknown error\n"); + sprintf(errormsg,"There was an unknown error(%li): %s",lerr,errormsg); + // strcpy(errormsg,"Unknown error"); + //strcpy(errormsg,"Setup was successful!"); + // strncpy(errormsg,herr,errormessagelength); + break; + } + return lerr; +} + +bool isInput(std::string in1, std::string in2, std::string def){ + // if the first equals the first + if ( 0 == Poco::icompare(in1, def.substr(0,1)) ) { + if ( 0 == Poco::icompare(in2, def.substr(1,1)) ) return true; + } else if ( 0 == Poco::icompare(in2, def.substr(0,1)) ) { + if ( 0 == Poco::icompare(in1, def.substr(1,1)) ) return true; + } + return false; +} + +double getT_refprop(double t) { + // t--temperature [K] + return t*1.; +} + +double getP_refprop(double p) { + // p--pressure [kPa] + return p/1000.0; +} + +double getD_refprop(double d) { + // d--bulk molar density [mol/L] + return d/dwm; // kg/m3 = g/l / g/mol = mol/l +} + +double getE_refprop(double e) { + // e--internal energy [J/mol] + return e*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getH_refprop(double h) { + // h--enthalpy [J/mol] + return h*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getS_refprop(double s) { + // s--entropy [[J/mol-K] + return s*dwm/1000.; // J/(kg.K) * g/mol * kg/(1000g) = J/(mol.K) +} + +/* + * Convert to SI units + */ +double getT_modelica() { + // t--temperature [K] + return dt; +} + +double getP_modelica() { + // p--pressure [kPa] + return dp*1000.0; +} + +double getD_modelica() { + // d--bulk molar density [mol/L] + return dd*dwm; // mol/l * g/mol = g/l = kg/m3 +} + +double getE_modelica() { + // e--internal energy [J/mol] + return de/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getH_modelica() { + // h--enthalpy [J/mol] + return dh/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getS_modelica() { + // s--entropy [[J/mol-K] + return ds/dwm * 1000.0; // J/(mol.K) / g/mol * 1000g/kg = J/(kg.K) +} + +double getWM_modelica(){ + //molecular weight + return dwm/1000; +} + +double getDL_modelica(){ + //density of liquid phase + return ddl*dwliq; // mol/l * g/mol = g/l = kg/m3 +} + +double getDV_modelica(){ + //density of gaseous phase + return ddv*dwvap; // mol/l * g/mol = g/l = kg/m3 +} + +double getQ_modelica(){ + //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + +// double dxlkg[ncmax], dxvkg[ncmax]; +// long lerr = 0; +// char* herr[errormessagelength]; +// QMASSlib(dqmol,dxmoll,dxmolv,dqkg,dxlkg,dxvkg,dwliq,dwvap,lerr,herr); +// if (lerr!=0) { +// printf("Error no. %li initialising REFPROP: \"%s\"\n", lerr, errormsg); +// return lerr; +// } +// c -19: input q < 0 or > 1 +// c herr--error string (character*255 variable if ierr<>0) + if (dwvap==noValue) WMOLlib(dxmolv,dwvap); + return dqmol*dwvap/dwm; +} + +double getCV_modelica(){ + return dCv/dwm * 1000.0; +} + +double getCP_modelica(){ + return dCp/dwm * 1000.0; +} + +double getW_modelica(){ + //speed of sound + return dw; +} + +double getWML_modelica(){ + if (dwliq==noValue) WMOLlib(dxmoll,dwliq); + return dwliq/1000.; +} + +double getWMV_modelica(){ + if (dwvap==noValue) WMOLlib(dxmolv,dwvap); + return dwvap/1000.; +} + +//double* getXL_modelica(){ +// double dxlkg[ncmax]; +// XMASSlib(dxmoll,dxlkg,dwliq); +// return dxlkg; +//} +// +//double* getXV_modelica(){ +// double dxvkg[ncmax]; +// XMASSlib(dxmolv,dxvkg,dwvap); +// return dxvkg; +//} + +double getETA_modelica(){ + return deta/1e6; +} + +double getTCX_modelica(){ + return dtcx; +} + + + +/* + * Checks if the provided variables match the currently active + * state. Needs the current values of the state properties as + * well as the new ones. Additionally, the mole based composition + * has to be provided with the number of components. + * Changing the amount of components or the fluids itself should + * be covered by the flushing routines above. + */ +bool isState(double var1, double val1, double var2, double val2, double xmol[], long nc){ + if (debug) printf ("\nChecking state.\n"); + if (abs(var1-val1)>delta) return false; + if (abs(var2-val2)>delta) return false; + //if (lnc!=nc) return false; + // If we have a mixture, we need to check the composition. + if (nc>1) { + for ( int i = 0; i < nc; i++ ) { + if (abs(dxmol[i]-xmol[i])>delta) return false; + } + } + if (debug) printf ("Going to return \"true\".\n"); + return true; +} + + +double getValue(std::string out) { + + if (debug) printf("\nChecking for %s \n",out.c_str()); + + if ( 0 == Poco::icompare(out, "p") ) { + if (dp!=noValue) return getP_modelica(); + } else if ( 0 == Poco::icompare(out, "t") ) { + if (dt!=noValue) return getT_modelica(); + } else if ( 0 == Poco::icompare(out, "m") ) { + if (dwm!=noValue) return getWM_modelica(); + } else if ( 0 == Poco::icompare(out, "d") ) { + if (dd!=noValue) return getD_modelica(); + } else if ( 0 == Poco::icompare(out, "e") ) { + if (de!=noValue) return getE_modelica(); + } else if ( 0 == Poco::icompare(out, "h") ) { + if (dh!=noValue) return getH_modelica(); + } else if ( 0 == Poco::icompare(out, "s") ) { + if (ds!=noValue) return getS_modelica(); + } else if ( 0 == Poco::icompare(out, "w") ) { + if (dw!=noValue) return getW_modelica(); + } else if ( 0 == Poco::icompare(out, "v") ) { + if (deta!=noValue) return getETA_modelica(); + } else if ( 0 == Poco::icompare(out, "l") ) { + if (dtcx!=noValue) return getTCX_modelica(); + } + return noValue; +} + + +double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevars: string of any combination of two variables out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevar1,statevar2: values of the two variables specified in statevars + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values (props[0] containing error number) + errormsg: string containing error message +*/ + //char statevars[3]; + //double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; + //long nX,ierr=0; //zero means no error + //char herr[errormessagelength+1]; +// HINSTANCE RefpropdllInstance;// Then have windows load the library. +// Poco::SharedLibrary RefpropdllInstance(""); + + long lerr = 0; + + +// DEBUGMODE = 1; + if (DEBUGMODE) debug = true; + std::string out = std::string(what).substr(0,1); + std::string in1 = std::string(statevars_in).substr(0,1); + std::string in2 = std::string(statevars_in).substr(1,1); + std::string fluids = std::string(fluidnames); + std::string rPath = std::string(REFPROP_PATH); + + + + + /* + * Call method to initialise the library and check for new fluids. + * Afterwards, the fluids have been processed and the constants might + * have been flushed. + */ + if (debug) printf("\nStarting function props_REFPROP to calculate %s.\n", out.c_str()); + + lerr = init_REFPROP(fluids, rPath, errormsg); + + if (lerr!=0) { + printf("Error no. %li initialising REFPROP: \"%s\"\n", lerr, errormsg); + return lerr; + } + + + /* + * Here should be the state checking to avoid unnecessary calculations. when + * working with mixtures, the constants also have to be flushed if the + * composition changes. + */ + // Convert mass-based composition to mole fractions and set molecular weight. + double* dxkg; + double dxmoltmp[ncmax]; + double dwmtmp; + //dxkg = (double*) calloc(ncmax,sizeof(double)); + //dxmoltmp = (double*) calloc(ncmax,sizeof(double)); + dxkg = x; + XMOLElib(dxkg,dxmoltmp,dwmtmp); + // dwm = dwm / 1000; // from g/mol to kg/mol + + double val1,val2,var1,var2,var,val; + double tmpValue; + std::string tmpVar; + for (int ii=1;ii<3;ii++){ + + if (ii==1) { + tmpVar = in1; + tmpValue = statevar1; + } else if (ii==2) { + tmpVar = in2; + tmpValue = statevar2; + } + + // loop through possible inputs + if ( 0 == Poco::icompare(tmpVar, "p") ) { + var = dp; + val = getP_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "T") ) { + var = dt; + val = getT_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "s") ) { + var = ds; + val = getS_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "h") ) { + var = dh; + val = getH_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "d") ) { + var = dd; + val = getD_refprop(tmpValue); + //} else if ( 0 == Poco::icompare(tmpVar, "q") ) { + // var = dqkg = tmpValue; + } else { + //lerr = 2; + //sprintf(errormsg,"Unknown state variable %i: %s",ii ,tmpVar.c_str()); + //return lerr; + } + + if (ii==1) { + val1 = val; + var1 = var; + } else if (ii==2) { + val2 = val; + var2 = var; + } + + //if (debug) printf("Checked input variable: %s\n",tmpVar.c_str()); + } + + bool knownState = isState(var1,val1,var2,val2,dxmoltmp,lnc); // dummies to force recalculation + double result = getValue(out); + bool valueExists = (result!=noValue); + + if (!knownState) { + if (lnc>1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %s: %f.\n",out.c_str(),result); + return result; + } + } + + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + // ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ) + + // Set variables to input values + if ( 0 == Poco::icompare(in1, in2) ) { + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); + return -1; + } + + memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; + //dxmol = dxmoltmp; + dwm = dwmtmp; + + double dqkg; + for (int ii=1;ii<3;ii++){ + + if (ii==1) { + tmpVar = in1; + tmpValue = statevar1; + } else if (ii==2) { + tmpVar = in2; + tmpValue = statevar2; + } + + // loop through possible inputs + if ( 0 == Poco::icompare(tmpVar, "p") ) { + dp = getP_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "T") ) { + dt = getT_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "s") ) { + ds = getS_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "h") ) { + dh = getH_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "d") ) { + dd = getD_refprop(tmpValue); + } else if ( 0 == Poco::icompare(tmpVar, "q") ) { + dqkg = tmpValue; + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable %i: %s",ii ,tmpVar.c_str()); + return lerr; + } + + if (debug) printf("Checked input variable: %s\n",tmpVar.c_str()); + } + + if (lerr==0){ + if (isInput(in1,in2,std::string("tp"))){ +// if (phase==2){ //fluid state is known to be two phase +// TPFL2lib(dt,dp,dxmol,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); +// }else{ + if (debug) printf("Calling TPFLSH with %f and %f.\n",dt,dp); + TPFLSHlib(dt,dp,dxmol,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + //if (debug) printf("Getting dd: %f\n",dd); +// } + }else if (isInput(in1,in2,std::string("ph"))){ +// if (phase==1){ //fluid state is known to be single phase +// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +//// if (liqvap==1) dl=d; else dv=d; +// }else{ + if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,dh); + PHFLSHlib(dp,dh,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("pd"))){ + if (phase==1){ //fluid state is known to be single phase + PDFL1lib(dp,dd,dxmol,dt,lerr,errormsg,errormessagelength); + }else{ + if (debug) printf("Calling PDFLSH with %f and %f.\n",dp,dd); + PDFLSHlib(dp,dd,dxmol,dt,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } + }else if (isInput(in1,in2,std::string("sp"))){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1(p,s,dxmol,kph,T,d,lerr,errormsg,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ + if (debug) printf("Calling PSFLSH with %f and %f.\n",dp,ds); + PSFLSHlib(dp,ds,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("pq"))){ + if (debug) printf("Calling PQFLSH with %f and %f.\n",dp,dqkg); + PQFLSHlib(dp,dqkg,dxmol,kq,dt,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// strcat(errormsg,"Bin in PQ!"); + }else if (isInput(in1,in2,std::string("th"))){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1(T,h,dxmol,Dmin,Dmax,d,lerr,errormsg,errormessagelength); + }else{*/ + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + if (debug) printf("Calling THFLSH with %f and %f.\n",dt,dh); + THFLSHlib(dt,dh,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("td"))){ + if (debug) printf("Calling TDFLSH with %f and %f.\n",dt,dd); + TDFLSHlib(dt,dd,dxmol,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("ts"))){ + long kr = 2; + if (debug) printf("Calling TSFLSH with %f and %f.\n",dt,ds); + TSFLSHlib(dt,ds,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("tq"))){ + if (debug) printf("Calling TQFLSH with %f and %f.\n",dt,dqkg); + TQFLSHlib(dt,dqkg,dxmol,kq,dp,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("dh"))){ + switch(phase){ //fluid state is known to be single phase + case 1: + DHFL1lib(dd,dh,dxmol,dt,lerr,errormsg,errormessagelength); + break; + case 2: + DHFL2lib(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); + break; + default: + if (debug) printf("Calling DHFLSH with %f and %f.\n",dd,dh); + DHFLSHlib(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + break; + } + }else if (isInput(in1,in2,std::string("hs"))){ + HSFLSHlib(dh,ds,dxmol,dt,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("ds"))){ + switch(phase){ //fluid state is known to be single phase + case 1: + DSFL1lib(dd,ds,dxmol,dt,lerr,errormsg,errormessagelength); + break; + case 2: + DSFL2lib(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); + break; + default: + if (debug) printf("Calling DSFLSH with %f and %f.\n",dd,ds); + DSFLSHlib(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + break; + } + }else + sprintf(errormsg,"Unknown combination of state variables! %s and %s", in1.c_str(), in2.c_str()); + } + + + switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE + case 'v': //dynamic viscosity uPa.s + case 'l': //thermal conductivity W/m.K + TRNPRPlib(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); + break; + } + + + switch(lerr){ + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 4: + sprintf(errormsg,"P=%f < 0",dp); + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",dt,dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); + break; + default: + //strncpy(errormsg,errormsg,errormessagelength); + break; + } + + +// //CONVERT TO SI-UNITS +// if (lerr==0){ +// WMOL(xliq,wmliq); +// wmliq /= 1000; //g/mol -> kg/mol +// WMOL(xvap,wmvap); +// wmvap /= 1000; //g/mol -> kg/mol +// //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); +// d *= wm*1000; //mol/dm� -> kg/m� +// dl *= wmliq*1000; //mol/dm� -> kg/m� +// dv *= wmvap*1000; //mol/dm� -> kg/m� +// e /= e/wm; //kJ/mol -> J/kg +// h /= wm; //kJ/mol -> J/kg +// s /= wm; //kJ/(mol�K) -> J/(kg�K) +// cv /= wm; +// cp /= wm; +// p *= 1000; //kPa->Pa +// if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis +// eta/=1e6; //uPa.s -> Pa.s +// } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica();//pressure in Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = getE_modelica(); //inner energy + props[9] = getH_modelica(); //specific enthalpy + props[10] = getS_modelica();//specific entropy + props[11] = getCV_modelica(); + props[12] = getCP_modelica(); + props[13] = getW_modelica(); //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + + double dxlkg[ncmax], dxvkg[ncmax]; + + XMASSlib(dxmoll,dxlkg,dwliq); + XMASSlib(dxmolv,dxvkg,dwvap); + + for (int dim=0; dimgetSymbol(WMOLdll_NAME); +// WMOL(x,wm); +//// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); +// if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); +// +// wm /= 1000; //g/mol -> kg/mol +// +// if (DEBUGMODE) printf("wm converted.\n"); + + + + long lerr = 0; + + +// DEBUGMODE = 1; + if (DEBUGMODE) debug = true; + std::string out = std::string(what).substr(0,1); + std::string in1 = std::string(statevar_in).substr(0,1); + std::string fluids = std::string(fluidnames); + std::string rPath = std::string(REFPROP_PATH); + + + /* + * Call method to initialise the library and check for new fluids. + * Afterwards, the fluids have been processed and the constants might + * have been flushed. + */ + if (debug) printf("\nStarting function satprops_REFPROP to calculate %s.\n", out.c_str()); + + lerr = init_REFPROP(fluids, rPath, errormsg); + + if (lerr!=0) { + printf("Error no. %li initialising REFPROP: \"%s\"\n", lerr, errormsg); + return lerr; + } + + + /* + * Here should be the state checking to avoid unnecessary calculations. when + * working with mixtures, the constants also have to be flushed if the + * composition changes. + */ + bool knownState = false; // dummies to force recalculation + bool valueExists = false; + + if (!knownState) { + if (lnc>1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %i: %f.\n",what[0],-1.0); + return -1.0; + } + } + + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + + // Convert mass-based composition to mole fractions and set molecular weight. + double* dxkg; + dxkg = x; + XMOLElib(dxkg,dxmol,dwm); + // dwm = dwm / 1000; // from g/mol to kg/mol + + // loop through possible inputs + if ( 0 == Poco::icompare(in1, "p") ) { + dp = getP_refprop(statevarval); + } else if ( 0 == Poco::icompare(in1, "t") ) { + dt = getT_refprop(statevarval); + } else if ( 0 == Poco::icompare(in1, "d") ) { + dd = getD_refprop(statevarval); + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); + return lerr; + } + if (debug) printf("\nstatevar %s checked\n",in1.c_str()); + + long j=2; +/* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) +*/ + long kph = -1; +/* kph--flag specifying desired root for multi-valued inputs + has meaning only for water at temperatures close to its triple point + -1 = return middle root (between 0 and 4 C) + 1 = return highest temperature root (above 4 C) + 3 = return lowest temperature root (along freezing line) */ + if (lerr==0) { + if ( 0 == Poco::icompare(in1, "t") ) { + SATTlib(dt,dxmol,j,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } else if ( 0 == Poco::icompare(in1, "p") ) { + SATPlib(dp,dxmol,j,dt,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + switch(lerr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + } else if ( 0 == Poco::icompare(in1, "d") ) { + SATDlib(dd,dxmol,j,kph,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + switch(lerr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } + } + + switch(lerr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 8: + sprintf(errormsg,"x out of range, %s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"T=%f and x=%s out of range",dt,printX(dxmol,lnc).c_str()); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + //strncpy(errormsg,herr,errormessagelength); + break; + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica();//pressure in kPa->Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = 0; + props[8] = 0; //inner energy + props[9] = 0; //specific enthalpy + props[10] = 0;//specific entropy + props[11] = 0; + props[12] = 0; + props[13] = 0; //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + + double dxlkg[ncmax], dxvkg[ncmax]; + + XMASSlib(dxmoll,dxlkg,dwliq); + XMASSlib(dxmolv,dxvkg,dwvap); + + for (int ii=0;ii + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -40,7 +43,7 @@ extern "C" { double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; // //double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, char * Ref); - double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, char * Ref, char * Path, char * herr, int DEBUGMODE); + //double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, std::string Ref, std::string Path, char * herr, int DEBUGMODE); #ifdef __cplusplus } #endif // __cplusplus diff --git a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp b/_wrapper/v0.6/src/refpropwrappertest.cpp similarity index 73% rename from _REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp rename to _wrapper/v0.6/src/refpropwrappertest.cpp index 439392a..7e64ee8 100644 --- a/_REFPROP-Wrapper/Version 0.5_linux/src/refpropwrappertest.cpp +++ b/_wrapper/v0.6/src/refpropwrappertest.cpp @@ -28,36 +28,38 @@ int main(int argc, char* argv[]){ x = (double*) calloc(nX,sizeof(double)); props=(double*) calloc(16+2*nX,sizeof(double)); - + sumx = 0; for (i=0;i Date: Sun, 25 Nov 2012 14:56:16 -0800 Subject: [PATCH 16/57] 2012:11:25 23:54 - Added linux source code to version 0.5, included the "free" routines to enable parallel use, removed the tolerances in the state check --- _wrapper/v0.5/refprop_wrapper_linux.cpp | 1252 ++++++++++++++++++++++ _wrapper/v0.6/Makefile | 2 +- _wrapper/v0.6/src/refprop_wrapper.cpp | 104 +- _wrapper/v0.6/src/refpropwrappertest.cpp | 2 +- readme.md | 2 +- 5 files changed, 1318 insertions(+), 44 deletions(-) create mode 100644 _wrapper/v0.5/refprop_wrapper_linux.cpp diff --git a/_wrapper/v0.5/refprop_wrapper_linux.cpp b/_wrapper/v0.5/refprop_wrapper_linux.cpp new file mode 100644 index 0000000..7a6c7ad --- /dev/null +++ b/_wrapper/v0.5/refprop_wrapper_linux.cpp @@ -0,0 +1,1252 @@ +/* + wrapper code for a static library containing functions from the dynamic library refprop.dll + to be used from Modelica + + This file is released under the Modelica License 2. + + Coded in 2010 by + Henning Francke + francke@gfz-potsdam.de + + Helmholtz Centre Potsdam + GFZ German Research Centre for Geosciences + Telegrafenberg, D-14473 Potsdam + + Modified for portability to Linux and + introduction of POCO library in 2012 by + Jorrit Wronski (jowr@mek.dtu.dk) + DTU Mechanical Engineering + + needs + refprop_lib.h - header for librefprop.so, based on examples + refprop_wrapper.h - header for static REFPROP_wrapper.a, also needed by Dymola + + Use the provided makefile to install the library file from source. +*/ + +//#define DEBUGMODE 1 + +#include +#if defined(WIN32) || defined(_WIN32) +# include +//# include "REFPROP_dll.h" +#else // assuming Linux system +# include +# include +//# include // dlopen etc +# include // tolower etc +#endif +#include +//# error "Could not determine system." +#include "refprop_wrapper.h" + +// get the POCO classes +#include "Poco/SharedLibrary.h" +#include "Poco/Path.h" +#include "Poco/File.h" +#include "Poco/Environment.h" +#include "Poco/StringTokenizer.h" +#include "Poco/String.h" +#include "Poco/Exception.h" + + +// Some constants... +const long maxstringlength=10000; +// const long filepathlength=1024; +// const long errormessagelength=255+filepathlength; +// const long lengthofreference=3; +// const long refpropcharlength=255; +// const long ncmax=20; // Note: ncmax is the max number of components + +Poco::SharedLibrary *RefpropdllInstance = NULL; +char loadedfluids[refpropcharlength]; +char loadedpath[filepathlength]; + +// Define the functions either by their pointers or type. +WMOLdll_POINTER WMOL = NULL; +TPFL2dll_POINTER TPFL2 = NULL; +TPFLSHdll_POINTER TPFLSH = NULL; +PHFL1dll_POINTER PHFL1 = NULL; +PHFLSHdll_POINTER PHFLSH = NULL; +PDFL1dll_POINTER PDFL1 = NULL; +PDFLSHdll_POINTER PDFLSH = NULL; +PSFLSHdll_POINTER PSFLSH = NULL; +PQFLSHdll_POINTER PQFLSH = NULL; +THFLSHdll_POINTER THFLSH = NULL; +TDFLSHdll_POINTER TDFLSH = NULL; +TSFLSHdll_POINTER TSFLSH = NULL; +TQFLSHdll_POINTER TQFLSH = NULL; +DHFL1dll_POINTER DHFL1 = NULL; +DHFL2dll_POINTER DHFL2 = NULL; +DHFLSHdll_POINTER DHFLSH = NULL; +HSFLSHdll_POINTER HSFLSH = NULL; +DSFL1dll_POINTER DSFL1 = NULL; +DSFL2dll_POINTER DSFL2 = NULL; +DSFLSHdll_POINTER DSFLSH = NULL; +TRNPRPdll_POINTER TRNPRP = NULL; +SATTdll_POINTER SATT = NULL; +SATPdll_POINTER SATP = NULL; +SATDdll_POINTER SATD = NULL; + +// char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { +// int i,n_ret; +// int newlen = strlen(replace); +// int oldlen = strlen(search); +// char *ret; +// *count = 0; +// +// //count occurrences of searchstring +// for (i = 0; oldlen && str[i]; ++i) +// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr +// ++*count, i+=oldlen - 1; +// } +// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); +// if (!ret){ +// printf("Could not allocate memory"); +// return ""; +// } +// +// if (!*count){ +// strncpy(ret,str,n_ret); +// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); +// }else{ +// i = 0; +// while (*str) +// if (strstr(str, search) == str) +// strncpy(&ret[i], replace,n_ret-i-1), +// i += newlen, +// str += oldlen; +// else +// ret[i++] = *str++; +// ret[i] = '\0'; +// } +// return ret; +// } + +//str_replace (fluidnames, "|", replace, nX) +char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { + + *count = 0; + char ret[maxstringlength]; + + std::string fluids(str); + std::string dlimit(search); + std::string substi(replace); + std::string result; + + // if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); + // if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); + // if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); + // if (DEBUGMODE) printf("nX: %li\n\n",*count); + + Poco::StringTokenizer tokens(fluids.c_str(), dlimit.c_str(), Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); + result = std::string(Poco::cat(substi, tokens.begin(), tokens.end())); + + strcpy(ret,result.c_str()); + //strcat(ret,'\0'); + + *count = tokens.count()-1; + + if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); + if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); + if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); + if (DEBUGMODE) printf("replaced: %s\n",result.c_str()); + if (DEBUGMODE) printf("nX: %li\n\n",*count); + +return ret; + +} + +// char printDoubleArray (double* arr[] ) { +// std::copy(arr.begin(),arr.end(),std::ostream_iterator(std::cout,", ")); +// } + +char *printX(double arr[], long nX) { + char ret[filepathlength]; + char tmp[filepathlength]; + strcpy(ret,"("); + //for(int i = 0; i < (sizeof(arr)-1); i++) { + for(int i = 0; i < (nX-2); i++) { + sprintf(tmp,"%f, ", arr[i]); + strcat(ret,tmp); + } + sprintf(tmp,"%f", arr[nX-1]); + strcat(ret,tmp); + + strcat(ret,")"); + //printf ("output: %s \n", ret); + return ret; +} + +int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ +// Sets up the interface to the REFPROP.DLL +// is called by props_REFPROP and satprops_REFPROP +// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; + + long ierr=0; +// DEBUGMODE = 1; + + if (strlen(REFPROP_PATH_CHAR)>filepathlength){ + sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %li)\n",strlen(REFPROP_PATH_CHAR),filepathlength); + return 0; + } + // Define temporary objects for checks. + char REF_PATH_CHAR[filepathlength]; + Poco::Path REF_PATH(true); + char FLUIDS_CHAR[filepathlength] = "fluids"; + Poco::Path FLD_PATH(true); + char LIBRARY_CHAR[filepathlength]; + Poco::Path LIB_PATH(true); + //Poco::File theFile; + + // Parse the string and append a path separator if necessary. + REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); + if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); + // Overwrite the provided path + strcpy(REF_PATH_CHAR,REF_PATH.toString().c_str()); + + // Check the path if running in debugmode + if (DEBUGMODE) { + Poco::File refFile(REF_PATH); + if ( !refFile.isDirectory() || !refFile.canRead() ){ + printf ("REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); + return 0; + } else { + printf ("REF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); + } + } + + // The fluid files are in the Refprop directory, append "fluids". + FLD_PATH.parse(REF_PATH_CHAR); + FLD_PATH.pushDirectory(FLUIDS_CHAR); + +// //std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... +// Poco::Path SRC_PATH; +// SRC_PATH.parse(Poco::Environment::get("PATH")); + +// if (DEBUGMODE) { +// // Determine which library file should be loaded +// bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); +// if (is_linux){ +// strcpy(LIBRARY_CHAR,"librefprop.so"); +// SRC_PATH.pushDirectory("/usr/local/lib"); +// } else { +// strcpy(LIBRARY_CHAR,"refprop.dll"); +// SRC_PATH.pushDirectory(REF_PATH.toString()); +// } + + + //bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); +// if (found_lib) { +// printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); +// } else { +// printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); +// } +// } else { +// LIB_PATH.parse(REF_PATH_CHAR); +// } + + //LIB_PATH.parse(LIBRARY_CHAR); + +// if (DEBUGMODE) { +// printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); +// printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); +// printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); +// printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); +// } + + Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... + + if (RefpropdllInstance==NULL) { // we need to load the library + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); + + // Check the OS and assign the right names for the library + bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); + if (is_linux){ + strcpy(LIBRARY_CHAR,"librefprop.so"); + SRC_PATH.parse("/usr/local/lib"); + } else { + strcpy(LIBRARY_CHAR,"refprop.dll"); + SRC_PATH = REF_PATH; + } + + // search the library at the given path + bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); + if (found_lib) { + if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + } else { + if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); + return 0; + } + + // check if the file is correct and executable + if (DEBUGMODE) { + Poco::File libFile(LIB_PATH); + if ( !libFile.isFile() || !libFile.canRead() ){ + printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + sprintf (errormsg,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); + return 0; + } else { + printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); + } + } + + // load a new library instance + RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); + + } else { // library was already loaded + if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); + } + + // Now the library is loaded and we can start checkicng the fluid path + if (DEBUGMODE) { + Poco::File fldFile(FLD_PATH); + if ( !fldFile.isDirectory() || !fldFile.canRead() ){ + printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); + return 0; + } else { + printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); + } + } + char FLD_PATH_CHAR[filepathlength]; + strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + + + if (DEBUGMODE) { + printf ("%s\n"," "); + printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); + printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); + printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); + printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); + printf ("%s\n"," "); + } + + + // Check for new fluids and if the library has to be loaded again. + bool isFluid = (strcmp(fluidnames,loadedfluids)==0); + bool isPath = (strcmp(REF_PATH_CHAR,loadedpath)==0); + if (DEBUGMODE) printf ("Comparison of fluids : %i \n", isFluid ); + if (DEBUGMODE) printf ("Comparison of path : %i \n\n", isPath ); + //if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); + + char *hf; + +// // // // if (isFluid && isPath) { +// // // // //sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); +// // // // if (DEBUGMODE) printf ("No setup needed, fluids (%s) and path (%s) did not change.\n\n", fluidnames,REF_PATH_CHAR); +// // // // // // // // return 0; +// // // // } else { + // we need to call setup + + char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; +// // // // char *hf; + + //parse fluid composition string and insert absolute paths + char replace[filepathlength+6]; + strcpy(replace,".FLD|"); + //if (DEBUGMODE) printf("REPLACE: %s\n",replace); + strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); + + //int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; + int hf_len = maxstringlength; + hf = (char*) calloc(hf_len, sizeof(char)); + + strncpy(hf,FLD_PATH_CHAR,hf_len); + + char replaced[filepathlength]; + + strcpy(replaced,str_replace(fluidnames, "|", replace, nX, DEBUGMODE)); + + //str_replace returns the number of delimiters -> nX, but components are one more ... + if (++*nX>ncmax){ //...that's why nX is incremented + sprintf(errormsg,"Too many components (More than %li)\n",ncmax); + return 0; + } + + + strncat(hf,replaced,hf_len-strlen(hf)); + + strncat(hf,".FLD",hf_len-strlen(hf)); + + if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); + + strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path + strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); + strcpy(hrf,"DEF"); + + + SETUPdll_POINTER SETUP = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); + if (DEBUGMODE) printf("Running SETUP...\n"); + //char hftmp[maxstringlength]; + //strcpy(hftmp,hf); + static char hfld[maxstringlength+1]; + strcpy(hfld,hf); + SETUP(*nX, hfld, hfmix, hrf, ierr, herr); + + strcpy(loadedfluids,fluidnames); + strcpy(loadedpath,REF_PATH_CHAR); + if (DEBUGMODE) printf("SETUP run complete (Error no: %li)\n",ierr); + + if (DEBUGMODE) printf("Error code processing...\n"); + switch(ierr){ + case 101: + //strcpy(errormsg,"error in opening file"); +// if (DEBUGMODE) printf("Error 101\n"); + sprintf(errormsg,"error in opening file %s",hf); + break; + case 102: +// if (DEBUGMODE) printf("Error 102\n"); + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: +// if (DEBUGMODE) printf("Error -103\n"); + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: +// if (DEBUGMODE) printf("Error 104\n"); + strcpy(errormsg,"error in setup of model"); + break; + case 105: +// if (DEBUGMODE) printf("Error 105\n"); + strcpy(errormsg,"specified model not found"); + break; + case 111: +// if (DEBUGMODE) printf("Error 111\n"); + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: +// if (DEBUGMODE) printf("Error 112\n"); + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: +// if (DEBUGMODE) printf("Error 114\n"); + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 0: + break; + default: +// if (DEBUGMODE) printf("Unknown error\n"); + strcpy(errormsg,"Unknown error"); + //strcpy(errormsg,"Setup was successful!"); + strncpy(errormsg,herr,errormessagelength); + break; + } +// // // // free(hf); + return ierr; + + +// if (DEBUGMODE) { +// theFile = Poco::File(LIB_PATH); +// if ( !theFile.isFile() || !theFile.canExecute() ){ +// sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); +// return 0; +// } +// } +// char LIB_PATH_CHAR[filepathlength]; +// strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); +// +// if (DEBUGMODE) { +// theFile = Poco::File(FLD_PATH); +// if ( !theFile.isDirectory() || !theFile.canRead() ){ +// sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); +// return 0; +// } +// } +// char FLD_PATH_CHAR[filepathlength]; +// strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); + +//// First we load the library with the POCO foundation +//// classes and then define all the needed functions +//// by their names and a cast to the correct type. +// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); +// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); +// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); +// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { +// RefpropdllInstance.unload(); +// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); +// RefpropdllInstance.load(LIB_PATH_CHAR); +// } +// +// if (!RefpropdllInstance.isLoaded()){ +// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); +// return 100; +// } + + +// char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; +// char *hf; +// +// //parse fluid composition string and insert absolute paths +// char replace[filepathlength+6]; +// strcpy(replace,".FLD|"); +// //if (DEBUGMODE) printf("REPLACE: %s\n",replace); +// strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); +// +// int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; +// hf = (char*) calloc(hf_len, sizeof(char)); +// +// strncpy(hf,FLD_PATH_CHAR,hf_len); +// strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... +// if (++*nX>ncmax){ //...that's why nX is incremented +// sprintf(errormsg,"Too many components (More than %i)\n",ncmax); +// return 0; +// } +// strncat(hf,".FLD",hf_len-strlen(hf)); +// if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); +// +// strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path +// strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); +// strcpy(hrf,"DEF"); +// +// +// // SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); +// if (DEBUGMODE) printf("Running SETUPdll...\n"); +// SETUP(*nX, hf, hfmix, hrf, ierr, herr); +// strcpy(loadedfluids,fluidnames); +// if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); +// +// // WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); +// // TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); +// // TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); +// // PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); +// // PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); +// // PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); +// // PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); +// // PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); +// // PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); +// // THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); +// // TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); +// // TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); +// // TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); +// // DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); +// // DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); +// // DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); +// // HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); +// // DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); +// // DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); +// // DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); +// // TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); +// // SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); +// // SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); +// // SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); + + +// // if (DEBUGMODE) printf("Error code processing...\n"); +// switch(ierr){ +// case 101: +// //strcpy(errormsg,"error in opening file"); +// // if (DEBUGMODE) printf("Error 101\n"); +// sprintf(errormsg,"error in opening file %s",hf); +// break; +// case 102: +// // if (DEBUGMODE) printf("Error 102\n"); +// strcpy(errormsg,"error in file or premature end of file"); +// break; +// case -103: +// // if (DEBUGMODE) printf("Error -103\n"); +// strcpy(errormsg,"unknown model encountered in file"); +// break; +// case 104: +// // if (DEBUGMODE) printf("Error 104\n"); +// strcpy(errormsg,"error in setup of model"); +// break; +// case 105: +// // if (DEBUGMODE) printf("Error 105\n"); +// strcpy(errormsg,"specified model not found"); +// break; +// case 111: +// // if (DEBUGMODE) printf("Error 111\n"); +// strcpy(errormsg,"error in opening mixture file"); +// break; +// case 112: +// // if (DEBUGMODE) printf("Error 112\n"); +// strcpy(errormsg,"mixture file of wrong type"); +// break; +// case 114: +// // if (DEBUGMODE) printf("Error 114\n"); +// strcpy(errormsg,"nc<>nc from setmod"); +// break; +// case 0: +// break; +// default: +// // if (DEBUGMODE) printf("Unknown error\n"); +// strcpy(errormsg,"Unknown error"); +// //strcpy(errormsg,"Setup was successful!"); +// strncpy(errormsg,herr,errormessagelength); +// break; +// } +// free(hf); +// return ierr; +} + + +double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevars: string of any combination of two variables out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevar1,statevar2: values of the two variables specified in statevars + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values (props[0] containing error number) + errormsg: string containing error message +*/ + char statevars[3]; + double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; + long nX,ierr=0; //zero means no error + char herr[errormessagelength+1]; +// HINSTANCE RefpropdllInstance;// Then have windows load the library. +// Poco::SharedLibrary RefpropdllInstance(""); + +// DEBUGMODE = 1; + + if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); + + //initialize interface to REFPROP.dll +// if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ +// printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); +// return 0; +// } + if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ + printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); + return 0; + } + + //CALCULATE MOLAR MASS +// WMOL = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); +// WMOLdll_TYPE * WMOL = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); + WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); + WMOL(x,wm); +// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); + wm /= 1000; //g/mol -> kg/mol + + //identify and assign passed state variables + statevars[0] = tolower(statevars_in[0]); + statevars[1] = tolower(statevars_in[1]); + statevars[2] = '\0'; + if (statevars[0]!='\0'){ + if (statevars[0]==statevars[1]){ + props[0] = 3; + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); + return 0; + } + for (int ii=0;ii<2;ii++){ + val = (ii==0?statevar1:statevar2); + switch(statevars[ii]){ + case 'p': + p = val/1000; //Pa->kPa + break; + case 't': + T = val; + break; + case 's': + s = val*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = val*wm; //J/kg --> kJ/mol + break; + case 'd': + d = val/wm/1000; //kg/m� -> mol/dm� + break; + case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + q = val; + break; + default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ + return 0; + } + } + } + +/* +//...If phase j is known, call TPRHO: + long j=2; //phase definition(j=1: Liquid, j=2: Vapor) + long tmp_int=0; + TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); + TPRHO(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); +*/ +//...If phase is not known, call TPFLSH + double xliq[ncmax],xvap[ncmax],f[ncmax]; + long kq=2;/* additional input--only for TQFLSH and PQFLSH + kq--flag specifying units for input quality + kq = 1 quality on MOLAR basis [moles vapor/total moles] + kq = 2 quality on MASS basis [mass vapor/total mass]*/ +// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); + if (ierr==0){ + if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ +// strcat(errormsg,"Bin in TP!"); + if (phase==2){ //fluid state is known to be two phase +// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); + TPFL2 = (TPFL2dll_POINTER) RefpropdllInstance->getSymbol(TPFL2dll_NAME); + TPFL2(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + }else{ +// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); + TPFLSH = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); + TPFLSH(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ +// if (phase==1){ //fluid state is known to be single phase +//// PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); +// PHFL1 = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); +// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +//// if (liqvap==1) dl=d; else dv=d; +// }else{ +//// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + PHFLSH = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); + PHFLSH(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ + if (phase==1){ //fluid state is known to be single phase +// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); + PDFL1 = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); + PDFL1(p,d,x,T,ierr,herr,errormessagelength); + }else{ +// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); + PDFLSH = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); + PDFLSH(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + } + }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); + PSFL1(p,s,x,kph,T,d,ierr,herr,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ +// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); + PSFLSH = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); + PSFLSH(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ +// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); + PQFLSH = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); + PQFLSH(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); +// strcat(errormsg,"Bin in PQ!"); + }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); + THFL1(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); + }else{*/ +// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); + THFLSH = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + THFLSH (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// } + }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ +// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + TDFLSH = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); + TDFLSH(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ +// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); + TSFLSH = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); + long kr = 2; + TSFLSH(T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ +// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); + TQFLSH = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); + TQFLSH(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); + DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); + DHFL1(d,h,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); + DHFL2 = (DHFL2dll_POINTER) RefpropdllInstance->getSymbol(DHFL2dll_NAME); + DHFL2(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); + DHFLSH = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); + DHFLSH(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + break; + } + }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ +// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); + HSFLSH = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); + HSFLSH(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); + }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ + switch(phase){ //fluid state is known to be single phase + case 1: +// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); + DSFL1 = (DSFL1dll_POINTER) RefpropdllInstance->getSymbol(DSFL1dll_NAME); + DSFL1(d,s,x,T,ierr,herr,errormessagelength); + break; + case 2: +// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); + DSFL2 = (DSFL2dll_POINTER) RefpropdllInstance->getSymbol(DSFL2dll_NAME); + DSFL2(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); + break; + default: +// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); + DSFLSH = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); + DSFLSH(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); + break; + } + }else + sprintf(errormsg,"Unknown combination of state variables! %s", statevars); + } + + switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE + case 'v': //dynamic viscosity uPa.s + case 'l': //thermal conductivity W/m.K +// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); + TRNPRP = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); + TRNPRP(T,d,x,eta,tcx,ierr,herr,errormessagelength); + break; + } + + + switch(ierr){ + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 4: + sprintf(errormsg,"P=%f < 0",p); + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",T,p); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(x,nX)); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(x,nX),T); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(x,nX),p); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(x,nX),T,p); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",d); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",d); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); + break; + default: + strncpy(errormsg,herr,errormessagelength); + break; + } + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOL(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOL(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� + e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) + cv /= wm; + cp /= wm; + p *= 1000; //kPa->Pa + if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis + eta/=1e6; //uPa.s -> Pa.s + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = e; //inner energy + props[9] = h; //specific enthalpy + props[10] = s;//specific entropy + props[11] = cv; + props[12] = cp; + props[13] = w; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;iigetSymbol(WMOLdll_NAME); + WMOL(x,wm); +// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); + if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); + + wm /= 1000; //g/mol -> kg/mol + + if (DEBUGMODE) printf("wm converted.\n"); + + if (DEBUGMODE) printf("statevar is %s \n",statevar_in); + //identify and assign passed state variables + // char tmpstr[1]; + // strcpy(tmpstr,statevar[0]); + // statevar = toLowerCase(tmpstr); + //statevar[0] = tolower(statevar[0]); + char statevar[1]; + statevar[0] = tolower(statevar_in[0]); + if (DEBUGMODE) printf("\nstatevar lowercase.\n"); + if (statevar[0]!='\0'){ +// if (strcmp(statevar[0],"")){ +// if (statevar[0] != NULL){ + if (DEBUGMODE) printf("\nentering statevar switch.\n"); + switch(statevar[0]){ + case 'p': + p = statevarval/1000; //Pa->kPa + break; + case 't': + T = statevarval; + break; + case 'd': + d = statevarval/wm/1000; //kg/m� -> mol/dm� + break; +/* case 's': + s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) + break; + case 'h': + h = statevarval*wm; //J/kg --> kJ/mol + break; +*/ default: + props[0] = 2; + sprintf(errormsg,"Unknown state variable: %f", statevarval); + return 0; + } + } + + if (DEBUGMODE) printf("\nstatevar checked.\n"); + + double xliq[ncmax],xvap[ncmax],f[ncmax]; + + long j=2,kr; +/* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) +*/ + if (ierr==0) { + if (~strcmp(statevar,"t")){ +// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); + SATT = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); + SATT(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + }else if (~strcmp(statevar,"p")){ +// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); + SATP = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); + SATP(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + }else if (~strcmp(statevar,"d")){ +// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); + SATD = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); + SATD(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); + switch(ierr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } + } + + switch(ierr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",T); + break; + case 8: + sprintf(errormsg,"x out of range, %s",printX(x,nX)); + break; + case 9: + sprintf(errormsg,"T=%f and x=%s out of range",T,printX(x,nX)); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + strncpy(errormsg,herr,errormessagelength); + break; + } + + /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); + SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); + SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ + + + //CONVERT TO SI-UNITS + if (ierr==0){ + WMOL(xliq,wmliq); + wmliq /= 1000; //g/mol -> kg/mol + WMOL(xvap,wmvap); + wmvap /= 1000; //g/mol -> kg/mol + //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); + d *= wm*1000; //mol/dm� -> kg/m� + dl *= wmliq*1000; //mol/dm� -> kg/m� + dv *= wmvap*1000; //mol/dm� -> kg/m� +/* e /= e/wm; //kJ/mol -> J/kg + h /= wm; //kJ/mol -> J/kg + s /= wm; //kJ/(mol�K) -> J/(kg�K) +*/ p *= 1000; //kPa->Pa + } + + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = ierr;//error code + props[1] = p;//pressure in kPa->Pa + props[2] = T; //Temperature in K + props[3] = wm; //molecular weight + props[4] = d; //density + props[5] = dl; //density of liquid phase + props[6] = dv; //density of liquid phase + props[7] = 0; + props[8] = 0; //inner energy + props[9] = 0; //specific enthalpy + props[10] = 0;//specific entropy + props[11] = 0; + props[12] = 0; + props[13] = 0; //speed of sound + props[14] = wmliq; + props[15] = wmvap; + for (int ii=0;iidelta) return false; - if (abs(var2-val2)>delta) return false; + if (var1!=val1) return false; + if (var2!=val2) return false; //if (lnc!=nc) return false; // If we have a mixture, we need to check the composition. if (nc>1) { for ( int i = 0; i < nc; i++ ) { - if (abs(dxmol[i]-xmol[i])>delta) return false; + if (dxmol[i]!=xmol[i]) return false; } } if (debug) printf ("Going to return \"true\".\n"); @@ -762,6 +770,37 @@ double getValue(std::string out) { return noValue; } +int updateProps(double *props, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica(); //pressure in Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = getE_modelica(); //inner energy + props[9] = getH_modelica(); //specific enthalpy + props[10] = getS_modelica(); //specific entropy + props[11] = getCV_modelica(); + props[12] = getCP_modelica(); + props[13] = getW_modelica(); //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + + double dxlkg[ncmax], dxvkg[ncmax]; + + XMASSlib(dxmoll,dxlkg,dwliq); + XMASSlib(dxmolv,dxvkg,dwvap); + + for (int dim=0; dim Pa.s // } - //ASSIGN VALUES TO RETURN ARRAY - props[0] = lerr;//error code - props[1] = getP_modelica();//pressure in Pa - props[2] = getT_modelica(); //Temperature in K - props[3] = getWM_modelica(); //molecular weight - props[4] = getD_modelica(); //density - props[5] = getDL_modelica(); //density of liquid phase - props[6] = getDV_modelica(); //density of liquid phase - props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = getE_modelica(); //inner energy - props[9] = getH_modelica(); //specific enthalpy - props[10] = getS_modelica();//specific entropy - props[11] = getCV_modelica(); - props[12] = getCP_modelica(); - props[13] = getW_modelica(); //speed of sound - props[14] = getWML_modelica(); - props[15] = getWMV_modelica(); - - double dxlkg[ncmax], dxvkg[ncmax]; - - XMASSlib(dxmoll,dxlkg,dwliq); - XMASSlib(dxmolv,dxvkg,dwvap); - - for (int dim=0; dimPa - props[2] = getT_modelica(); //Temperature in K + props[1] = getP_modelica(); //pressure in kPa->Pa + props[2] = getT_modelica(); //Temperature in K props[3] = getWM_modelica(); //molecular weight - props[4] = getD_modelica(); //density + props[4] = getD_modelica(); //density props[5] = getDL_modelica(); //density of liquid phase props[6] = getDV_modelica(); //density of liquid phase props[7] = 0; props[8] = 0; //inner energy props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy + props[10] = 0; //specific entropy props[11] = 0; props[12] = 0; props[13] = 0; //speed of sound diff --git a/_wrapper/v0.6/src/refpropwrappertest.cpp b/_wrapper/v0.6/src/refpropwrappertest.cpp index 7e64ee8..dba7729 100644 --- a/_wrapper/v0.6/src/refpropwrappertest.cpp +++ b/_wrapper/v0.6/src/refpropwrappertest.cpp @@ -71,7 +71,7 @@ int main(int argc, char* argv[]){ printf("Xvap[%i]=%f\n",ii+1, props[16+nX+ii]); } - props_REFPROP ("v", argv[1], argv[2] , props, atof(argv[3]), atof(argv[4]), x, 0, argv[5] , errormsg, DEBUG); + props_REFPROP ("s", argv[1], argv[2] , props, atof(argv[3]), atof(argv[4]), x, 0, argv[5] , errormsg, DEBUG); // props_REFPROP("", "pT" , "isobutan|propane", props, 1e5 , 293.0 , x, 0, "/opt/refprop/", errormsg, DEBUG); printf("Errormessage: %s\n",errormsg); diff --git a/readme.md b/readme.md index 646a9da..6d444e1 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ For Windows, please follow these instructions For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. 1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. -2. Change the paths in `_wrapper/v0.5_linux/Makefile` to your needs. +2. Change the paths in `_wrapper/v0.6/Makefile` to your needs. 3. Make sure to have the shared library `librefprop.so` available in the same directory as the `fluids` folder. You might want to check https://github.com/jowr/librefprop.so for details. 4. Got to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. 5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; From a9f18fb956a19eef5a5f947681e87f0b821ff20f Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 27 Nov 2012 03:01:34 -0800 Subject: [PATCH 17/57] 2012:11:27 11:58 - Added header file for refprop library that works on windows and linux, fixed array bug in flushing routines, updated description with link to Poco on GitHub. --- _wrapper/v0.6/src/refprop_lib.h | 674 ++++++++++++++++++++++++++ _wrapper/v0.6/src/refprop_wrapper.cpp | 99 +--- readme.md | 2 +- 3 files changed, 686 insertions(+), 89 deletions(-) create mode 100644 _wrapper/v0.6/src/refprop_lib.h diff --git a/_wrapper/v0.6/src/refprop_lib.h b/_wrapper/v0.6/src/refprop_lib.h new file mode 100644 index 0000000..1a95963 --- /dev/null +++ b/_wrapper/v0.6/src/refprop_lib.h @@ -0,0 +1,674 @@ + +#ifndef REFPROP_H +#define REFPROP_H +// The idea here is to have a common header for Windows +// and Linux systems. The Windows branch should cover the +// functions provided by the .dll and the Linux part covers +// the compiled .so file. Name changes caused by gfortran +// are repsected and should be accounted for. +// +// Define data types that match the Fortran definitions. This is also +// a possible starting point to introduce platform independence. +// Partly taken from: http://arnholm.org/software/cppf77/cppf77.htm#Section5 +// An issue with characters still needs to be solved. +//#include +// The other data types can be handled: +typedef long INTEGER; +typedef float REAL; +typedef double DOUBLE_PRECISION; +typedef int LOGICAL; +// +// Do some manual changes to the function names +// if needed. +#if defined(WIN32) || defined(_WIN32) +// Define compiler specific calling conventions +// for the shared library. +# define LIBRARY_API __stdcall // __declspec(dllexport) +// Do not define function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll +#else // defined(WIN32) || defined(_WIN32) +// Define compiler specific calling conventions +// for the shared library. +# define LIBRARY_API +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # ifdef _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +#endif // defined(WIN32) || defined(_WIN32), else branch +// +// +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#ifdef __cplusplus +extern "C" { +#endif + // extra function for setup + typedef void (LIBRARY_API RPVersion_TYPE )( char* ); + typedef void (LIBRARY_API SETPATHdll_TYPE)( const char* ); + // + typedef void (LIBRARY_API ABFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ABFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API ACTVYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API AGdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CCRITdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CP0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CRITPdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CV2PKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API CVCPKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API CVCPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DBFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DBFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DDDPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DDDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DHD1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DIELECdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DOTFILLdll_TYPE)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DPDD2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API DPTSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API DSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API DSFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API ENTHALdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ENTROdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API ESFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API FGCTYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); + typedef void (LIBRARY_API FPVdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API GERG04dll_TYPE)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API GETFIJdll_TYPE)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API GIBBSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API HSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API INFOdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API LIMITKdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API LIMITSdll_TYPE)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); + typedef void (LIBRARY_API LIMITXdll_TYPE)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + typedef void (LIBRARY_API MELTPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MELTTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API MLTH2Odll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API NAMEdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API PDFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PREOSdll_TYPE)(INTEGER &); + typedef void (LIBRARY_API PRESSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API PSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API PUREFLDdll_TYPE)(INTEGER &); + typedef void (LIBRARY_API QMASSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API QMOLEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SATTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETAGAdll_TYPE)(INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMIXdll_TYPE)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETMODdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETREFdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); + //typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); + typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*); +// typedef void (LIBRARY_API SPECGRdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); // not found in library + typedef void (LIBRARY_API SUBLPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SUBLTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURFTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API SURTENdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API THERM0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERM3dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THERMdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); + typedef void (LIBRARY_API THFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TPFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke + typedef void (LIBRARY_API TPRHOdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TRNPRPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API TSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); + typedef void (LIBRARY_API VIRBdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API VIRCdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API WMOLdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMASSdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + typedef void (LIBRARY_API XMOLEdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); + // + // Declare the functions for direct access + RPVersion_TYPE RPVersion; + SETPATHdll_TYPE SETPATHdll; + ABFL1dll_TYPE ABFL1dll; + ABFL2dll_TYPE ABFL2dll; + ACTVYdll_TYPE ACTVYdll; + AGdll_TYPE AGdll; + CCRITdll_TYPE CCRITdll; + CP0dll_TYPE CP0dll; + CRITPdll_TYPE CRITPdll; + CSATKdll_TYPE CSATKdll; + CV2PKdll_TYPE CV2PKdll; + CVCPKdll_TYPE CVCPKdll; + CVCPdll_TYPE CVCPdll; + DBDTdll_TYPE DBDTdll; + DBFL1dll_TYPE DBFL1dll; + DBFL2dll_TYPE DBFL2dll; + DDDPdll_TYPE DDDPdll; + DDDTdll_TYPE DDDTdll; + DEFLSHdll_TYPE DEFLSHdll; + DHD1dll_TYPE DHD1dll; + DHFLSHdll_TYPE DHFLSHdll; + DHFL1dll_TYPE DHFL1dll; + DHFL2dll_TYPE DHFL2dll; + DIELECdll_TYPE DIELECdll; + DOTFILLdll_TYPE DOTFILLdll; + DPDD2dll_TYPE DPDD2dll; + DPDDKdll_TYPE DPDDKdll; + DPDDdll_TYPE DPDDdll; + DPDTKdll_TYPE DPDTKdll; + DPDTdll_TYPE DPDTdll; + DPTSATKdll_TYPE DPTSATKdll; + DSFLSHdll_TYPE DSFLSHdll; + DSFL1dll_TYPE DSFL1dll; + DSFL2dll_TYPE DSFL2dll; + ENTHALdll_TYPE ENTHALdll; + ENTROdll_TYPE ENTROdll; + ESFLSHdll_TYPE ESFLSHdll; + FGCTYdll_TYPE FGCTYdll; + FPVdll_TYPE FPVdll; + GERG04dll_TYPE GERG04dll; + GETFIJdll_TYPE GETFIJdll; + GETKTVdll_TYPE GETKTVdll; + GIBBSdll_TYPE GIBBSdll; + HSFLSHdll_TYPE HSFLSHdll; + INFOdll_TYPE INFOdll; + LIMITKdll_TYPE LIMITKdll; + LIMITSdll_TYPE LIMITSdll; + LIMITXdll_TYPE LIMITXdll; + MELTPdll_TYPE MELTPdll; + MELTTdll_TYPE MELTTdll; + MLTH2Odll_TYPE MLTH2Odll; + NAMEdll_TYPE NAMEdll; + PDFL1dll_TYPE PDFL1dll; + PDFLSHdll_TYPE PDFLSHdll; + PEFLSHdll_TYPE PEFLSHdll; + PHFL1dll_TYPE PHFL1dll; + PHFLSHdll_TYPE PHFLSHdll; + PQFLSHdll_TYPE PQFLSHdll; + PREOSdll_TYPE PREOSdll; + PRESSdll_TYPE PRESSdll; + PSFL1dll_TYPE PSFL1dll; + PSFLSHdll_TYPE PSFLSHdll; + PUREFLDdll_TYPE PUREFLDdll; + QMASSdll_TYPE QMASSdll; + QMOLEdll_TYPE QMOLEdll; + SATDdll_TYPE SATDdll; + SATEdll_TYPE SATEdll; + SATHdll_TYPE SATHdll; + SATPdll_TYPE SATPdll; + SATSdll_TYPE SATSdll; + SATTdll_TYPE SATTdll; + SETAGAdll_TYPE SETAGAdll; + SETKTVdll_TYPE SETKTVdll; + SETMIXdll_TYPE SETMIXdll; + SETMODdll_TYPE SETMODdll; + SETREFdll_TYPE SETREFdll; + SETUPdll_TYPE SETUPdll; +// SPECGRdll_TYPE SPECGRdll; // not found in library + SUBLPdll_TYPE SUBLPdll; + SUBLTdll_TYPE SUBLTdll; + SURFTdll_TYPE SURFTdll; + SURTENdll_TYPE SURTENdll; + TDFLSHdll_TYPE TDFLSHdll; + TEFLSHdll_TYPE TEFLSHdll; + THERM0dll_TYPE THERM0dll; + THERM2dll_TYPE THERM2dll; + THERM3dll_TYPE THERM3dll; + THERMdll_TYPE THERMdll; + THFLSHdll_TYPE THFLSHdll; + TPFLSHdll_TYPE TPFLSHdll; + TPFL2dll_TYPE TPFL2dll; + TPRHOdll_TYPE TPRHOdll; + TQFLSHdll_TYPE TQFLSHdll; + TRNPRPdll_TYPE TRNPRPdll; + TSFLSHdll_TYPE TSFLSHdll; + VIRBdll_TYPE VIRBdll; + VIRCdll_TYPE VIRCdll; + WMOLdll_TYPE WMOLdll; + XMASSdll_TYPE XMASSdll; + XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; +#ifdef __cplusplus +} // extern "C" +#endif +// REFPROP_H +#endif diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp index 4ddb025..1426c1e 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ b/_wrapper/v0.6/src/refprop_wrapper.cpp @@ -95,25 +95,6 @@ std::string printX(double arr[], long nc) { return ret; } - - - - - - - - - - - - - - - - - - - /* * Define pointer to library as well as the @@ -193,11 +174,11 @@ int flushProperties(){ ds=noValue; dqmol=noValue; dd=noValue; - dxmol[ncmax]=noValue; + dxmol[0]=noValue; ddl=noValue; ddv=noValue; - dxmoll[ncmax]=noValue; - dxmolv[ncmax]=noValue; + dxmoll[0]=noValue; + dxmolv[0]=noValue; dCv=noValue; dCp=noValue; dw=noValue; @@ -450,8 +431,8 @@ int setFluid(std::string fluid, char* error){ if (debug) printf("RefString: %s \n",RefString.c_str()); hf = (char*) calloc(refpropcharlong, sizeof(char)); - hfmix = (char*) calloc(refpropcharlong, sizeof(char)); - hrf = (char*) calloc(refpropcharlong, sizeof(char)); + hfmix = (char*) calloc(refpropcharlength+8, sizeof(char)); + hrf = (char*) calloc(refpropcharlength, sizeof(char)); strcpy(hf,RefString.c_str()); strcpy(hfmix,FLD_PATH.toString().c_str()); @@ -657,20 +638,12 @@ double getDV_modelica(){ } double getQ_modelica(){ - //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - -// double dxlkg[ncmax], dxvkg[ncmax]; -// long lerr = 0; -// char* herr[errormessagelength]; -// QMASSlib(dqmol,dxmoll,dxmolv,dqkg,dxlkg,dxvkg,dwliq,dwvap,lerr,herr); -// if (lerr!=0) { -// printf("Error no. %li initialising REFPROP: \"%s\"\n", lerr, errormsg); -// return lerr; -// } -// c -19: input q < 0 or > 1 -// c herr--error string (character*255 variable if ierr<>0) - if (dwvap==noValue) WMOLlib(dxmolv,dwvap); - return dqmol*dwvap/dwm; + if (lnc>1 && abs(dqmol)<990) { // maintain special values + if (dwvap==noValue) WMOLlib(dxmolv,dwvap); + return dqmol*dwvap/dwm; + } else { + return dqmol; + } } double getCV_modelica(){ @@ -1172,26 +1145,6 @@ OUTPUT } -// //CONVERT TO SI-UNITS -// if (lerr==0){ -// WMOL(xliq,wmliq); -// wmliq /= 1000; //g/mol -> kg/mol -// WMOL(xvap,wmvap); -// wmvap /= 1000; //g/mol -> kg/mol -// //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); -// d *= wm*1000; //mol/dm� -> kg/m� -// dl *= wmliq*1000; //mol/dm� -> kg/m� -// dv *= wmvap*1000; //mol/dm� -> kg/m� -// e /= e/wm; //kJ/mol -> J/kg -// h /= wm; //kJ/mol -> J/kg -// s /= wm; //kJ/(mol�K) -> J/(kg�K) -// cv /= wm; -// cp /= wm; -// p *= 1000; //kPa->Pa -// if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis -// eta/=1e6; //uPa.s -> Pa.s -// } - updateProps(props, lerr); if ( 0 == Poco::icompare(out, "p") ) { @@ -1251,36 +1204,6 @@ OUTPUT props: Array containing all calculated values errormsg: string containing error message */ -// double p, T, d, val, dl,dv,wm,wmliq,wmvap; -// long nX,ierr=0; -// char herr[errormessagelength+1]; -//// HINSTANCE RefpropdllInstance; -//// void* RefpropdllInstance; -//// Poco::SharedLibrary RefpropdllInstance(""); -// -//// DEBUGMODE = 1; -// -// if (DEBUGMODE) printf("\nStarting function satprops_REFPROP...\n"); -// -// //initialize interface to REFPROP.dll -// if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ -// printf("Error no. %f initializing REFPROP: \"%s\"\n", props[0], errormsg); -// return 0; -// } -// -// if (DEBUGMODE) printf("\nFunction init_REFPROP was called\n"); -// -// //CALCULATE MOLAR MASS -//// WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); -// WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); -// WMOL(x,wm); -//// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); -// if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); -// -// wm /= 1000; //g/mol -> kg/mol -// -// if (DEBUGMODE) printf("wm converted.\n"); - long lerr = 0; diff --git a/readme.md b/readme.md index 6d444e1..f0a137b 100644 --- a/readme.md +++ b/readme.md @@ -21,7 +21,7 @@ For installing on a Linux machine, please follow the instructions in the Makefil 4. Got to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. 5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; -To remove the files from your system, please use `sudo make uninstall`. Please be aware that you need a copy of the Poco C++ framework to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/. The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. +To remove the files from your system, please use `sudo make uninstall`. Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it via your package manager with `sudo apt-get install libpoco-dev` .The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. From cf7694cfbea68308c86f597343507489a71fba28 Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 28 Nov 2012 02:58:23 -0800 Subject: [PATCH 18/57] 2012:11:28 11:55 - Changed external library name to lower case. Added static library for Linux --- REFPROPMedium/getProp_REFPROP.mo | 2 +- REFPROPMedium/getSatProp_REFPROP.mo | 2 +- REFPROPMediumPureSubstance/getProp_REFPROP.mo | 2 +- .../getSatProp_REFPROP.mo | 2 +- _wrapper/v0.6/Makefile | 21 +++++++++++-- _wrapper/v0.6/Makefile.bat | 25 ++++++++++++++++ _wrapper/v0.6/src/refprop_wrapper.h | 2 +- readme.md | 30 ++++++++++++------- 8 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 _wrapper/v0.6/Makefile.bat diff --git a/REFPROPMedium/getProp_REFPROP.mo b/REFPROPMedium/getProp_REFPROP.mo index ecdb4dc..ade4a0a 100644 --- a/REFPROPMedium/getProp_REFPROP.mo +++ b/REFPROPMedium/getProp_REFPROP.mo @@ -15,5 +15,5 @@ function getProp_REFPROP external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); -annotation (Include="#include ", Library="REFPROP_wrapper"); +annotation (Include="#include ", Library="refprop_wrapper"); end getProp_REFPROP; diff --git a/REFPROPMedium/getSatProp_REFPROP.mo b/REFPROPMedium/getSatProp_REFPROP.mo index 3849893..7e59f44 100644 --- a/REFPROPMedium/getSatProp_REFPROP.mo +++ b/REFPROPMedium/getSatProp_REFPROP.mo @@ -13,5 +13,5 @@ function getSatProp_REFPROP external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - annotation (Include="#include ", Library="REFPROP_wrapper"); + annotation (Include="#include ", Library="refprop_wrapper"); end getSatProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getProp_REFPROP.mo b/REFPROPMediumPureSubstance/getProp_REFPROP.mo index 5d9ae73..4e4dc1b 100644 --- a/REFPROPMediumPureSubstance/getProp_REFPROP.mo +++ b/REFPROPMediumPureSubstance/getProp_REFPROP.mo @@ -15,5 +15,5 @@ function getProp_REFPROP external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); -annotation (Include="#include ", Library="REFPROP_wrapper"); +annotation (Include="#include ", Library="refprop_wrapper"); end getProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo b/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo index becabb7..3d50d64 100644 --- a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo +++ b/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo @@ -13,5 +13,5 @@ function getSatProp_REFPROP external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - annotation (Include="#include ", Library="REFPROP_wrapper"); + annotation (Include="#include ", Library="refprop_wrapper"); end getSatProp_REFPROP; diff --git a/_wrapper/v0.6/Makefile b/_wrapper/v0.6/Makefile index cc1bf29..0992eea 100644 --- a/_wrapper/v0.6/Makefile +++ b/_wrapper/v0.6/Makefile @@ -1,7 +1,7 @@ # ============================================================================ # Name : Makefile # Author : Jorrit Wronski (jowr@mek.dtu.dk) -# Version : 0.3 +# Version : 0.6 # Copyright : Use and modify at your own risk. # Description : Makefile for Refprop from Fortran and C++ tests. # ============================================================================ @@ -26,6 +26,8 @@ THENAME =refprop_wrapper LIBRARYEXTENSION =.so THETEST =refpropwrappertest +# find . -type f -print0 | xargs -0 sed -i 's/!REFPROP_wrapper/refprop_wrapper/g' +# find . -type f -print0 | xargs -0 sed -i 's/refprop_wrapper/refprop_wrapper/g' ########################################################### # Setting the directories for library, header and # binary files created in this makefile. @@ -64,7 +66,10 @@ HEADEREXTENSION =.h # Copy files to places recognised by the system. ########################################################### .PHONY : install -install : header library +install : install_dynamic + +.PHONY : install_dynamic +install_dynamic : header library $(MK) $(HEADINST) $(LIBINST) $(CP) $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) $(CP) $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) @@ -74,10 +79,20 @@ install : header library $(LN) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) $(LD) +.PHONY : install_static +install_static : header $(LIBRARY).a + $(MK) $(HEADINST) $(LIBINST) + $(CP) $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(LIBRARY).a $(LIBINST)/$(LIBRARY).a + $(CH) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CH) $(LIBINST)/$(LIBRARY).a + $(LD) + .PHONY : uninstall uninstall : unfixit $(RM) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) $(RM) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION)* + $(RM) $(LIBINST)/$(LIBRARY).a .PHONY : all all : header library @@ -86,11 +101,13 @@ all : header library fixit : install ln -sf $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) ln -sf $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) + ln -sf $(LIBINST)/$(LIBRARY).a $(LIBINST)/libREFPROP_wrapper .PHONY : unfixit unfixit : $(RM) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) $(RM) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) + $(RM) $(LIBINST)/libREFPROP_wrapper ########################################################## # Compile the C++ sources into a library file that can diff --git a/_wrapper/v0.6/Makefile.bat b/_wrapper/v0.6/Makefile.bat new file mode 100644 index 0000000..304447d --- /dev/null +++ b/_wrapper/v0.6/Makefile.bat @@ -0,0 +1,25 @@ +@echo off +setlocal +REM ============================================================================ +REM Name : Makefile.bat +REM Author : Jorrit Wronski (jowr@mek.dtu.dk) +REM Version : 0.6 +REM Copyright : Use and modify at your own risk. +REM Description : Batch script to install the static wrapper library +REM ============================================================================ +REM The installation procedure should be as follows: +REM 0) make sure to have the refprop.dll available on your system +REM 1) Check the paths in this file and correct them if necessary. +REM 2) run this file +REM ============================================================================ +REM To compile the sources you can use +REM cl /c refprop_wrapper.cpp +REM lib refprop_wrapper.obj +REM ============================================================================ +REM +REM Set the required directories, could be %ProgramFiles% or %ProgramFiles(x86)% +SET PROG_DIR=%ProgramFiles(x86)% +SET DYMO_VER="Dymola 2013" +SET DYMO_DIR=%PROG_DIR%\%DYMO_VER% +COPY "refprop_wrapper.lib" "%DYMO_DIR%\bin\lib\" +COPY "src\refprop_wrapper.h" "%DYMO_DIR%\Source\" diff --git a/_wrapper/v0.6/src/refprop_wrapper.h b/_wrapper/v0.6/src/refprop_wrapper.h index acf1fd8..7b71851 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.h +++ b/_wrapper/v0.6/src/refprop_wrapper.h @@ -1,5 +1,5 @@ /* - header file for REFPROP_wrapper.cpp + header file for refprop_wrapper.cpp This file is released under the Modelica License 2. diff --git a/readme.md b/readme.md index f0a137b..3c97886 100644 --- a/readme.md +++ b/readme.md @@ -3,25 +3,35 @@ This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. ## Installation Instructions +If you only want to run the wrapper without compiling it from source, you can use the provided makefiles to install the precompiled static libraries. ### Windows -For Windows, please follow these instructions +**Since I do not run Windows myself, I am not able to try this myself. Could you, dear Windows users, please provide me with feedback and the actual `.lib` files needed for the instructions below to work.** -1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. -2. Copy `\wrapper\v0.5\REFPROP_WRAPPER.LIB` to `%DYMOLADIR%\\BIN\\LIB\` (%DYMOLADIR% is DYMOLA's program directory) -3. Copy `\wrapper\v0.5\REFPROP_WRAPPER.H` to `%DYMOLADIR%\\SOURCE\\` -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; +> For Windows, please follow these instructions +> +> 1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. +> 2. Double click on `_wrapper\v0.6\Makefile.bat` +> 3. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; +> ### Linux -For installing on a Linux machine, please follow the instructions in the Makefile provided in the directory containing the Linux version of the wrapper class. You only have to type in the right directories and install all the compilers / libraries required. +For installing on a Linux machine, please follow these instructions 1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. -2. Change the paths in `_wrapper/v0.6/Makefile` to your needs. +2. Open a command prompt in `_wrapper/v0.6/` and run `sudo make install_static`. 3. Make sure to have the shared library `librefprop.so` available in the same directory as the `fluids` folder. You might want to check https://github.com/jowr/librefprop.so for details. -4. Got to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. -5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; + +## Compiling + +### Windows +Please feel free to contribute to this part of the work. I was told that the code works with VisualStudio and VisualStudio Express, but I cannot provide instructions or feedback. + +### Linux +For compiling on a Linux machine, please follow the instructions in the Makefile provided in the directory of the wrapper sources. You might have to adjust some directorie names and install all the compilers and libraries required. -To remove the files from your system, please use `sudo make uninstall`. Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it via your package manager with `sudo apt-get install libpoco-dev` .The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. +Afterwards, you can go to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. This compiles and installs a dynamic library on your system. To remove the files from your system, please use `sudo make uninstall`. Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it via your package manager with `sudo apt-get install libpoco-dev` .The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. From 24a9d18646bf174f0ad578497687cbf6e88f6c62 Mon Sep 17 00:00:00 2001 From: jowr Date: Fri, 22 Feb 2013 22:23:21 +0100 Subject: [PATCH 19/57] 2013:02:22 22:21 - Added derivatives of density with respect to enthalpy at constant pressure and with respect to pressure at constant enthalpy to the wrapper. Major rewrite of the interface and the Refprop package. Should be easier to use now. --- Examples/package.mo | 3 - Examples/package.order | 2 - Interfaces/MixtureInputChoice.mo | 6 + Interfaces/PartialMixtureTwoPhaseMediumTwo.mo | 939 +++++++++ Interfaces/PureSubstanceInputChoice.mo | 6 + Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 1842 +++++++++++++++++ Interfaces/package.mo | 4 + Interfaces/package.order | 4 + Media/Pentane.mo | 5 + Media/R410mix.mo | 5 + Media/package.mo | 3 + Media/package.order | 2 + PartialMixtureTwoPhaseMedium/FixedPhase.mo | 3 - PartialMixtureTwoPhaseMedium/FluidLimits.mo | 21 - PartialMixtureTwoPhaseMedium/package.mo | 728 ------- PartialMixtureTwoPhaseMedium/package.order | 61 - REFPROPMedium/StrJoin.mo | 11 - REFPROPMedium/density_ThX.mo | 16 - REFPROPMedium/density_TsX.mo | 16 - REFPROPMedium/density_hsX.mo | 16 - REFPROPMedium/density_pqX.mo | 16 - REFPROPMedium/getProp_REFPROP.mo | 19 - REFPROPMedium/getProp_REFPROP_check.mo | 23 - REFPROPMedium/getSatProp_REFPROP.mo | 17 - REFPROPMedium/getSatProp_REFPROP_check.mo | 21 - REFPROPMedium/package.mo | 597 ------ REFPROPMedium/package.order | 75 - REFPROPMedium/partialREFPROP.mo | 9 - REFPROPMedium/pressure_ThX.mo | 16 - REFPROPMedium/pressure_TqX.mo | 16 - REFPROPMedium/pressure_TsX.mo | 16 - REFPROPMedium/pressure_dTX.mo | 16 - REFPROPMedium/pressure_dsX.mo | 16 - REFPROPMedium/pressure_hdX.mo | 16 - REFPROPMedium/pressure_hsX.mo | 16 - REFPROPMedium/setState.mo | 45 - REFPROPMedium/setState_ThX.mo | 15 - REFPROPMedium/setState_TsX.mo | 15 - REFPROPMedium/setState_dsX.mo | 15 - REFPROPMedium/setState_hdX.mo | 15 - REFPROPMedium/setState_hsX.mo | 15 - REFPROPMedium/setState_pdX.mo | 15 - REFPROPMedium/setState_pqX.mo | 15 - REFPROPMedium/specificEnthalpy_TsX.mo | 19 - REFPROPMedium/specificEnthalpy_dsX.mo | 23 - REFPROPMedium/specificEnthalpy_pdX.mo | 19 - REFPROPMedium/specificEnthalpy_pqX.mo | 17 - REFPROPMedium/specificEntropy_ThX.mo | 20 - REFPROPMedium/specificEntropy_dTX.mo | 17 - REFPROPMedium/specificEntropy_hdX.mo | 16 - REFPROPMedium/specificEntropy_pdX.mo | 16 - REFPROPMedium/specificEntropy_phX.mo | 21 - REFPROPMedium/specificEntropy_pqX.mo | 15 - REFPROPMedium/temperature_dsX.mo | 16 - REFPROPMedium/temperature_hdX.mo | 16 - REFPROPMedium/temperature_hsX.mo | 16 - REFPROPMedium/temperature_pdX.mo | 16 - REFPROPMedium/temperature_pqX.mo | 15 - REFPROPMediumPureSubstance/StrJoin.mo | 11 - REFPROPMediumPureSubstance/density_ThX.mo | 16 - REFPROPMediumPureSubstance/density_TsX.mo | 16 - REFPROPMediumPureSubstance/density_hsX.mo | 16 - REFPROPMediumPureSubstance/density_pqX.mo | 16 - REFPROPMediumPureSubstance/getProp_REFPROP.mo | 19 - .../getProp_REFPROP_check.mo | 23 - .../getSatProp_REFPROP.mo | 17 - .../getSatProp_REFPROP_check.mo | 21 - REFPROPMediumPureSubstance/package.mo | 592 ------ REFPROPMediumPureSubstance/package.order | 78 - REFPROPMediumPureSubstance/partialREFPROP.mo | 9 - REFPROPMediumPureSubstance/pressure_ThX.mo | 16 - REFPROPMediumPureSubstance/pressure_TqX.mo | 16 - REFPROPMediumPureSubstance/pressure_TsX.mo | 16 - REFPROPMediumPureSubstance/pressure_dTX.mo | 16 - REFPROPMediumPureSubstance/pressure_dsX.mo | 16 - REFPROPMediumPureSubstance/pressure_hdX.mo | 16 - REFPROPMediumPureSubstance/pressure_hsX.mo | 16 - REFPROPMediumPureSubstance/setState.mo | 45 - REFPROPMediumPureSubstance/setState_ThX.mo | 15 - REFPROPMediumPureSubstance/setState_TsX.mo | 15 - REFPROPMediumPureSubstance/setState_dsX.mo | 15 - REFPROPMediumPureSubstance/setState_hdX.mo | 15 - REFPROPMediumPureSubstance/setState_hsX.mo | 15 - REFPROPMediumPureSubstance/setState_pdX.mo | 15 - REFPROPMediumPureSubstance/setState_pqX.mo | 15 - .../specificEnthalpy_TsX.mo | 19 - .../specificEnthalpy_dTX.mo | 19 - .../specificEnthalpy_dsX.mo | 22 - .../specificEnthalpy_pdX.mo | 18 - .../specificEnthalpy_pqX.mo | 16 - .../specificEntropy_ThX.mo | 20 - .../specificEntropy_dTX.mo | 17 - .../specificEntropy_hdX.mo | 16 - .../specificEntropy_pdX.mo | 16 - .../specificEntropy_phX.mo | 21 - .../specificEntropy_pqX.mo | 15 - REFPROPMediumPureSubstance/temperature_dsX.mo | 16 - REFPROPMediumPureSubstance/temperature_hdX.mo | 16 - REFPROPMediumPureSubstance/temperature_hsX.mo | 16 - REFPROPMediumPureSubstance/temperature_pdX.mo | 16 - REFPROPMediumPureSubstance/temperature_pqX.mo | 15 - Testers/PentaneTester.mo | 52 + {Examples => Testers}/PropsMixture.mo | 115 +- Testers/PropsMixtureTwo.mo | 15 + {Examples => Testers}/PropsPureSubstance.mo | 104 +- Testers/R410mixTester.mo | 15 + .../Water_MixtureTwoPhase_pT.mo | 605 +++--- Testers/package.mo | 3 + Testers/package.order | 6 + Water_MixtureTwoPhase_pT/package.order | 20 - _wrapper/v0.5/REFPROP_wrapper.lib | Bin 39946 -> 39942 bytes _wrapper/v0.6/Makefile | 4 +- _wrapper/v0.6/bin/librefprop_wrapper.so | Bin 0 -> 249080 bytes _wrapper/v0.6/src/refprop_wrapper.cpp | 94 +- _wrapper/v0.6/src/refpropwrappertest.cpp | 11 +- package.mo | 49 +- package.order | 10 +- readme.md | 4 +- 118 files changed, 3418 insertions(+), 4057 deletions(-) delete mode 100644 Examples/package.mo delete mode 100644 Examples/package.order create mode 100644 Interfaces/MixtureInputChoice.mo create mode 100644 Interfaces/PartialMixtureTwoPhaseMediumTwo.mo create mode 100644 Interfaces/PureSubstanceInputChoice.mo create mode 100644 Interfaces/REFPROPMixtureTwoPhaseMedium.mo create mode 100644 Interfaces/package.mo create mode 100644 Interfaces/package.order create mode 100644 Media/Pentane.mo create mode 100644 Media/R410mix.mo create mode 100644 Media/package.mo create mode 100644 Media/package.order delete mode 100644 PartialMixtureTwoPhaseMedium/FixedPhase.mo delete mode 100644 PartialMixtureTwoPhaseMedium/FluidLimits.mo delete mode 100644 PartialMixtureTwoPhaseMedium/package.mo delete mode 100644 PartialMixtureTwoPhaseMedium/package.order delete mode 100644 REFPROPMedium/StrJoin.mo delete mode 100644 REFPROPMedium/density_ThX.mo delete mode 100644 REFPROPMedium/density_TsX.mo delete mode 100644 REFPROPMedium/density_hsX.mo delete mode 100644 REFPROPMedium/density_pqX.mo delete mode 100644 REFPROPMedium/getProp_REFPROP.mo delete mode 100644 REFPROPMedium/getProp_REFPROP_check.mo delete mode 100644 REFPROPMedium/getSatProp_REFPROP.mo delete mode 100644 REFPROPMedium/getSatProp_REFPROP_check.mo delete mode 100644 REFPROPMedium/package.mo delete mode 100644 REFPROPMedium/package.order delete mode 100644 REFPROPMedium/partialREFPROP.mo delete mode 100644 REFPROPMedium/pressure_ThX.mo delete mode 100644 REFPROPMedium/pressure_TqX.mo delete mode 100644 REFPROPMedium/pressure_TsX.mo delete mode 100644 REFPROPMedium/pressure_dTX.mo delete mode 100644 REFPROPMedium/pressure_dsX.mo delete mode 100644 REFPROPMedium/pressure_hdX.mo delete mode 100644 REFPROPMedium/pressure_hsX.mo delete mode 100644 REFPROPMedium/setState.mo delete mode 100644 REFPROPMedium/setState_ThX.mo delete mode 100644 REFPROPMedium/setState_TsX.mo delete mode 100644 REFPROPMedium/setState_dsX.mo delete mode 100644 REFPROPMedium/setState_hdX.mo delete mode 100644 REFPROPMedium/setState_hsX.mo delete mode 100644 REFPROPMedium/setState_pdX.mo delete mode 100644 REFPROPMedium/setState_pqX.mo delete mode 100644 REFPROPMedium/specificEnthalpy_TsX.mo delete mode 100644 REFPROPMedium/specificEnthalpy_dsX.mo delete mode 100644 REFPROPMedium/specificEnthalpy_pdX.mo delete mode 100644 REFPROPMedium/specificEnthalpy_pqX.mo delete mode 100644 REFPROPMedium/specificEntropy_ThX.mo delete mode 100644 REFPROPMedium/specificEntropy_dTX.mo delete mode 100644 REFPROPMedium/specificEntropy_hdX.mo delete mode 100644 REFPROPMedium/specificEntropy_pdX.mo delete mode 100644 REFPROPMedium/specificEntropy_phX.mo delete mode 100644 REFPROPMedium/specificEntropy_pqX.mo delete mode 100644 REFPROPMedium/temperature_dsX.mo delete mode 100644 REFPROPMedium/temperature_hdX.mo delete mode 100644 REFPROPMedium/temperature_hsX.mo delete mode 100644 REFPROPMedium/temperature_pdX.mo delete mode 100644 REFPROPMedium/temperature_pqX.mo delete mode 100644 REFPROPMediumPureSubstance/StrJoin.mo delete mode 100644 REFPROPMediumPureSubstance/density_ThX.mo delete mode 100644 REFPROPMediumPureSubstance/density_TsX.mo delete mode 100644 REFPROPMediumPureSubstance/density_hsX.mo delete mode 100644 REFPROPMediumPureSubstance/density_pqX.mo delete mode 100644 REFPROPMediumPureSubstance/getProp_REFPROP.mo delete mode 100644 REFPROPMediumPureSubstance/getProp_REFPROP_check.mo delete mode 100644 REFPROPMediumPureSubstance/getSatProp_REFPROP.mo delete mode 100644 REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo delete mode 100644 REFPROPMediumPureSubstance/package.mo delete mode 100644 REFPROPMediumPureSubstance/package.order delete mode 100644 REFPROPMediumPureSubstance/partialREFPROP.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_ThX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_TqX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_TsX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_dTX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_dsX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_hdX.mo delete mode 100644 REFPROPMediumPureSubstance/pressure_hsX.mo delete mode 100644 REFPROPMediumPureSubstance/setState.mo delete mode 100644 REFPROPMediumPureSubstance/setState_ThX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_TsX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_dsX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_hdX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_hsX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_pdX.mo delete mode 100644 REFPROPMediumPureSubstance/setState_pqX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_ThX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_dTX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_hdX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_pdX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_phX.mo delete mode 100644 REFPROPMediumPureSubstance/specificEntropy_pqX.mo delete mode 100644 REFPROPMediumPureSubstance/temperature_dsX.mo delete mode 100644 REFPROPMediumPureSubstance/temperature_hdX.mo delete mode 100644 REFPROPMediumPureSubstance/temperature_hsX.mo delete mode 100644 REFPROPMediumPureSubstance/temperature_pdX.mo delete mode 100644 REFPROPMediumPureSubstance/temperature_pqX.mo create mode 100644 Testers/PentaneTester.mo rename {Examples => Testers}/PropsMixture.mo (84%) create mode 100644 Testers/PropsMixtureTwo.mo rename {Examples => Testers}/PropsPureSubstance.mo (89%) create mode 100644 Testers/R410mixTester.mo rename Water_MixtureTwoPhase_pT/package.mo => Testers/Water_MixtureTwoPhase_pT.mo (88%) create mode 100644 Testers/package.mo create mode 100644 Testers/package.order delete mode 100644 Water_MixtureTwoPhase_pT/package.order create mode 100644 _wrapper/v0.6/bin/librefprop_wrapper.so diff --git a/Examples/package.mo b/Examples/package.mo deleted file mode 100644 index f55d44b..0000000 --- a/Examples/package.mo +++ /dev/null @@ -1,3 +0,0 @@ -within MediaTwoPhaseMixture; -package Examples -end Examples; diff --git a/Examples/package.order b/Examples/package.order deleted file mode 100644 index f8a6ea5..0000000 --- a/Examples/package.order +++ /dev/null @@ -1,2 +0,0 @@ -PropsMixture -PropsPureSubstance diff --git a/Interfaces/MixtureInputChoice.mo b/Interfaces/MixtureInputChoice.mo new file mode 100644 index 0000000..4a0ded6 --- /dev/null +++ b/Interfaces/MixtureInputChoice.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Interfaces; +type MixtureInputChoice = enumeration( + dTX "(d,T,X) as inputs", + phX "(p,h,X) as inputs", + psX "(p,s,X) as inputs", + pTX "(p,T,X) as inputs"); diff --git a/Interfaces/PartialMixtureTwoPhaseMediumTwo.mo b/Interfaces/PartialMixtureTwoPhaseMediumTwo.mo new file mode 100644 index 0000000..7680773 --- /dev/null +++ b/Interfaces/PartialMixtureTwoPhaseMediumTwo.mo @@ -0,0 +1,939 @@ +within REFPROP2Modelica.Interfaces; +partial package PartialMixtureTwoPhaseMediumTwo + "Template class for two phase medium of a mixture of substances " + extends Modelica.Media.Interfaces.PartialMixtureMedium; + constant Boolean smoothModel = false + "true if the (derived) model should not generate state events"; + constant Boolean onePhase = false + "true if the (derived) model should never be called with two-phase inputs"; + + constant FluidConstants mixtureFluidConstants( + iupacName = "mixture", + casRegistryNumber = "mixture", + chemicalFormula = "mixture", + structureFormula = "mixture", + molarMass = 0.001, + criticalTemperature = 0, + criticalPressure = 0, + criticalMolarVolume = 0, + acentricFactor = 0, + triplePointTemperature = 0, + triplePointPressure = 0, + meltingPoint = 0, + normalBoilingPoint = 0, + dipoleMoment = 0); + // The following values are not constant! + + import InputChoice = REFPROP2Modelica.Interfaces.MixtureInputChoice; + +constant InputChoice inputChoice=MixtureInputChoice.phX + "Default choice of input variables for property computations"; + type FixedPhase = Integer(min=0,max=2) + "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; + record FluidLimits "validity limits for fluid model" + extends Modelica.Icons.Record; + Temperature TMIN "minimum temperature"; + Temperature TMAX "maximum temperature"; + Density DMIN "minimum density"; + Density DMAX "maximum density"; + AbsolutePressure PMIN "minimum pressure"; + AbsolutePressure PMAX "maximum pressure"; + SpecificEnthalpy HMIN "minimum enthalpy"; + SpecificEnthalpy HMAX "maximum enthalpy"; + SpecificEntropy SMIN "minimum entropy"; + SpecificEntropy SMAX "maximum entropy"; + annotation(Documentation( + info=" +

The minimum pressure mostly applies to the liquid state only. + The minimum density is also arbitrary, but is reasonable for techical + applications to limit iterations in non-linear systems. The limits in + enthalpy and entropy are used as safeguards in inverse iterations.

+ ")); + end FluidLimits; + +redeclare replaceable record extends ThermodynamicState + "Thermodynamic state of two phase medium" + MolarMass molarMass "Molar mass of bulk mixture"; + FixedPhase phase(min=0, max=2) + "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; + //PrandtlNumber Pr "prandtl number"; + //Temperature T "temperature"; + VelocityOfSound a "velocity of sound"; + //Modelica.SIunits.CubicExpansionCoefficient beta + //"isobaric expansion coefficient"; + SpecificHeatCapacity cp "specific heat capacity cp"; + SpecificHeatCapacity cv "specific heat capacity cv"; + Density d "density"; + DerDensityByEnthalpy ddhp + "derivative of density wrt enthalpy at constant pressure"; + DerDensityByPressure ddph + "derivative of density wrt pressure at constant enthalpy"; + //DynamicViscosity eta "dynamic viscosity"; + SpecificEnthalpy h "specific enthalpy"; + //Modelica.SIunits.Compressibility kappa "compressibility"; + //ThermalConductivity lambda "thermal conductivity"; + //AbsolutePressure p "pressure"; + SpecificEntropy s "specific entropy"; + //MassFraction X[nX] "Mass fraction of components in kg/kg"; + annotation(Documentation(info="")); +end ThermodynamicState; + + replaceable record SaturationProperties + "Saturation properties of two phase medium" + extends Modelica.Icons.Record; + Temperature Tsat "saturation temperature"; + // Real dTp "derivative of Ts wrt pressure"; + // DerDensityByPressure ddldp "derivative of dls wrt pressure"; + // DerDensityByPressure ddvdp "derivative of dvs wrt pressure"; + // DerEnthalpyByPressure dhldp "derivative of hls wrt pressure"; + // DerEnthalpyByPressure dhvdp "derivative of hvs wrt pressure"; + // Density dl "density at bubble line (for pressure ps)"; + // Density dv "density at dew line (for pressure ps)"; + // SpecificEnthalpy hl "specific enthalpy at bubble line (for pressure ps)"; + // SpecificEnthalpy hv "specific enthalpy at dew line (for pressure ps)"; + AbsolutePressure psat "saturation pressure"; + // SurfaceTension sigma "surface tension"; + // SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; + // SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; + MassFraction X[nX] "Bulk mass fractions"; + // MassFraction Xl[nX] "Mass fractions of liquid phase"; + // MassFraction Xv[nX] "Mass fractions of gaseous phase"; + // annotation(Documentation(info="")); + end SaturationProperties; + +redeclare replaceable model extends BaseProperties( + p(stateSelect = if preferredMediumStates and + (basePropertiesInputChoice == InputChoice.phX or + basePropertiesInputChoice == InputChoice.pTX or + basePropertiesInputChoice == InputChoice.psX) then + StateSelect.prefer else StateSelect.default), + T(stateSelect = if preferredMediumStates and + (basePropertiesInputChoice == InputChoice.pTX or + basePropertiesInputChoice == InputChoice.dTX) then + StateSelect.prefer else StateSelect.default), + h(stateSelect = if preferredMediumStates and + basePropertiesInputChoice == InputChoice.phX then + StateSelect.prefer else StateSelect.default), + d(stateSelect = if preferredMediumStates and + basePropertiesInputChoice == InputChoice.dTX then + StateSelect.prefer else StateSelect.default)) + import REFPROP2Modelica.Interfaces.MixtureInputChoice; + parameter MixtureInputChoice basePropertiesInputChoice = inputChoice + "Choice of input variables for property computations"; + FixedPhase phaseInput + "Phase input for property computation functions, 2 for two-phase, 1 for one-phase, 0 if not known"; + Integer phaseOutput + "Phase output for medium, 2 for two-phase, 1 for one-phase"; + SpecificEntropy s( + stateSelect = if basePropertiesInputChoice == InputChoice.psX then + StateSelect.prefer else StateSelect.default) + "Specific entropy"; + SaturationProperties sat "saturation property record"; +equation + MM = state.molarMass; + R = Modelica.Constants.R/MM; + if (onePhase or (basePropertiesInputChoice == InputChoice.pTX)) then + phaseInput = 1 "Force one-phase property computation"; + else + phaseInput = 0 "Unknown phase"; + end if; + if (basePropertiesInputChoice == InputChoice.phX) then + // Compute the state record (including the unique ID) + state = + setState_phX( + p, + h, + X, + phaseInput); + // Compute the remaining variables. + // It is not possible to use the standard functions like + // d = density(state), because differentiation for index + // reduction and change of state variables would not be supported + // density_ph(), which has an appropriate derivative annotation, + // is used instead. The implementation of density_ph() uses + // setState with the same inputs, so there's no actual overhead + d = density_phX(p, h, X, phaseInput); + s = specificEntropy_phX(p, h, X, phaseInput); + T = temperature_phX(p, h, X, phaseInput); + elseif (basePropertiesInputChoice == InputChoice.dTX) then + state = + setState_dTX( + d, + T, + X, + phaseInput); + h = specificEnthalpy(state); + p = pressure(state); + s = specificEntropy(state); + elseif (basePropertiesInputChoice == InputChoice.pTX) then + state = + setState_pTX( + p, + T, + X, + phaseInput); + d = density(state); + h = specificEnthalpy(state); + s = specificEntropy(state); + elseif (basePropertiesInputChoice == InputChoice.psX) then + state = + setState_psX( + p, + s, + X, + phaseInput); + d = density(state); + h = specificEnthalpy(state); + T = temperature(state); + end if; + // Compute the internal energy + u = h - p/d; + // Compute the saturation properties record + sat = setSat_pX(state.p,state.X); + // Event generation for phase boundary crossing + if smoothModel then + // No event generation + phaseOutput = state.phase; + else + // Event generation at phase boundary crossing + if basePropertiesInputChoice == InputChoice.phX then + phaseOutput = if ((h > bubbleEnthalpy(sat) and h < dewEnthalpy(sat)) and + p < fluidConstants[1].criticalPressure) then 2 else 1; + elseif basePropertiesInputChoice == InputChoice.dTX then + phaseOutput = if ((d < bubbleDensity(sat) and d > dewDensity(sat)) and + T < fluidConstants[1].criticalTemperature) then 2 else 1; + elseif basePropertiesInputChoice == InputChoice.psX then + phaseOutput = if ((s > bubbleEntropy(sat) and s < dewEntropy(sat)) and + p < fluidConstants[1].criticalPressure) then 2 else 1; + else + // basePropertiesInputChoice == pTX + phaseOutput = 1; + end if; + end if; +end BaseProperties; + +// redeclare replaceable partial model extends BaseProperties +// "Base properties (p, d, T, h, s, u, R, MM, sat) of two phase medium" +// // Temperature T(start=300); +// Modelica.SIunits.SpecificEntropy s; +// SaturationProperties sat "Saturation properties at the medium pressure"; +// annotation(Documentation(info="")); +// end BaseProperties; + + replaceable partial function getMolarMass + extends Modelica.Icons.Function; + output MolarMass MM "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getMolarMass; + + replaceable partial function getCriticalTemperature + extends Modelica.Icons.Function; + output Temperature Tcrit "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalTemperature; + + replaceable partial function getCriticalPressure + extends Modelica.Icons.Function; + output AbsolutePressure Pcrit "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalPressure; + + replaceable partial function getCriticalMolarVolume + extends Modelica.Icons.Function; + output MolarVolume v "Molar mass of the mixture"; + annotation (Documentation(info="")); + end getCriticalMolarVolume; + + replaceable partial function setDewState + "Return the thermodynamic state on the dew line" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation point"; + input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; + output ThermodynamicState state "complete thermodynamic state info"; + annotation(Documentation(info="")); + end setDewState; + + replaceable partial function setBubbleState + "Return the thermodynamic state on the bubble line" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation point"; + input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; + output ThermodynamicState state "complete thermodynamic state info"; + annotation(Documentation(info="")); + end setBubbleState; + + redeclare replaceable partial function extends setState_dTX + "Return thermodynamic state as function of d, T and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_dTX; + + redeclare replaceable partial function extends setState_phX + "Return thermodynamic state as function of p, h and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_phX; + + redeclare replaceable partial function extends setState_psX + "Return thermodynamic state as function of p, s and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_psX; + + redeclare replaceable partial function extends setState_pTX + "Return thermodynamic state as function of p, T and composition X or Xi" + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + annotation(Documentation(info="")); + end setState_pTX; + + replaceable function setSat_TX + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat.Tsat := T; + sat.psat := saturationPressure(T,X); + sat.X := X; + annotation(Documentation(info="")); + end setSat_TX; + + replaceable function setSat_pX + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat.psat := p; + sat.Tsat := saturationTemperature(p,X); + sat.X := X; + annotation(Documentation(info="")); + end setSat_pX; + +/* +Functions to obtain fluid properties from the currently active state. +*/ + + replaceable partial function bubbleEnthalpy + "Return bubble point specific enthalpy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEnthalpy hl "boiling curve specific enthalpy"; + annotation(Documentation(info="")); + end bubbleEnthalpy; + + replaceable partial function dewEnthalpy "Return dew point specific enthalpy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEnthalpy hv "dew curve specific enthalpy"; + annotation(Documentation(info="")); + end dewEnthalpy; + + replaceable partial function bubbleEntropy + "Return bubble point specific entropy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEntropy sl "boiling curve specific entropy"; + annotation(Documentation(info="")); + end bubbleEntropy; + + replaceable partial function dewEntropy "Return dew point specific entropy" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SpecificEntropy sv "dew curve specific entropy"; + annotation(Documentation(info="")); + end dewEntropy; + + replaceable partial function bubbleDensity "Return bubble point density" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Density dl "boiling curve density"; + annotation(Documentation(info="")); + end bubbleDensity; + + replaceable partial function dewDensity "Return dew point density" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Density dv "dew curve density"; + annotation(Documentation(info="")); + end dewDensity; + + replaceable partial function saturationPressure "Return saturation pressure" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + output AbsolutePressure p "saturation pressure"; + annotation(Documentation(info="")); + end saturationPressure; + + function saturationPressure_der "Return saturation pressure time derivative" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + input Real T_der "Temperature derivative"; + output Real p_der "saturation pressure derivative"; + // Standard definition + algorithm + p_der :=T_der/saturationTemperature_derp_sat(setSat_TX(T,X)); + annotation(Inline = true); + end saturationPressure_der; + + replaceable function saturationPressure_sat "Return saturation temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output AbsolutePressure p "saturation pressure"; + algorithm + p := sat.psat; + annotation(Documentation(info="")); + end saturationPressure_sat; + + replaceable partial function saturationTemperature + "Return saturation temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[:]={1} "fluid composition as mass fractions"; + output Temperature T "saturation temperature"; + annotation(Documentation(info="")); + end saturationTemperature; + + replaceable function saturationTemperature_sat + "Return saturation temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Temperature T "saturation temperature"; + algorithm + T := sat.Tsat; + annotation(Documentation(info="")); + end saturationTemperature_sat; + + replaceable partial function saturationTemperature_derp + "Return derivative of saturation temperature w.r.t. pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + output Real dTp "derivative of saturation temperature w.r.t. pressure"; + annotation(Documentation(info="")); + end saturationTemperature_derp; + + replaceable function saturationTemperature_derp_sat + "Return derivative of saturation temperature w.r.t. pressure" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output Real dTp "derivative of saturation temperature w.r.t. pressure"; + algorithm + dTp := saturationTemperature_derp(sat.psat); + annotation(Documentation(info="")); + end saturationTemperature_derp_sat; + + /* redeclare replaceable partial function extends molarMass + "Return the molar mass of the medium" + algorithm + MM := fluidConstants[1].molarMass; + end molarMass;*/ + + replaceable partial function dBubbleDensity_dPressure + "Return bubble point density derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerDensityByPressure ddldp "boiling curve density derivative"; + annotation(Documentation(info="")); + end dBubbleDensity_dPressure; + + replaceable partial function dDewDensity_dPressure + "Return dew point density derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerDensityByPressure ddvdp "saturated steam density derivative"; + annotation(Documentation(info="")); + end dDewDensity_dPressure; + + replaceable partial function dBubbleEnthalpy_dPressure + "Return bubble point specific enthalpy derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerEnthalpyByPressure dhldp + "boiling curve specific enthalpy derivative"; + annotation(Documentation(info="")); + end dBubbleEnthalpy_dPressure; + + replaceable partial function dDewEnthalpy_dPressure + "Return dew point specific enthalpy derivative" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output DerEnthalpyByPressure dhvdp + "saturated steam specific enthalpy derivative"; + annotation(Documentation(info="")); + end dDewEnthalpy_dPressure; + + redeclare replaceable function density_phX + "Return density from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "density"; + algorithm + d := density( + setState_phX( + p, + h, + X, + phase)); + annotation(Documentation(info="")); + end density_phX; + + redeclare replaceable function density_psX + "Return density from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end density_psX; + + redeclare replaceable function density_pTX + "Return density from p, T, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_pTX( + p, + T, + X, + phase)); + annotation(Documentation(info="")); + end density_pTX; + +replaceable function specificEnthalpy_dTX + "Return specific enthalpy from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Pressure"; + input Temperature T "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := specificEnthalpy( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEnthalpy_dTX; + + redeclare replaceable function specificEnthalpy_psX + "Return specific enthalpy from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + h := specificEnthalpy( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_psX; + + redeclare replaceable function specificEnthalpy_pTX + "Return specific enthalpy from pressure, temperature and mass fraction" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "Specific enthalpy at p, T, X"; + algorithm + h := specificEnthalpy( + setState_pTX( + p, + T, + X, + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_pTX; + +replaceable function specificEntropy_phX + "Return specific entropy from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_phX( + p, + h, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_phX; + + redeclare replaceable function temperature_phX + "Return temperature from p, h, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + T := temperature( + setState_phX( + p, + h, + X, + phase)); + annotation(Documentation(info="")); + end temperature_phX; + + redeclare replaceable function temperature_psX + "Return temperature from p, s, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 + "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + T := temperature( + setState_psX( + p, + s, + X, + phase)); + annotation(Documentation(info="")); + end temperature_psX; + + replaceable function setState_dT "Return thermodynamic state from d and T" + extends Modelica.Icons.Function; + input Density d "density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_dTX( + d, + T, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_dT; + + replaceable function setState_ph "Return thermodynamic state from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_phX( + p, + h, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_ph; + + replaceable function setState_ps "Return thermodynamic state from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_psX( + p, + s, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_ps; + + replaceable function setState_pT "Return thermodynamic state from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := + setState_pTX( + p, + T, + fill(0, 0), + phase); + annotation(Documentation(info="")); + end setState_pT; + + replaceable function setState_px + "Return thermodynamic state from pressure and vapour quality" + input AbsolutePressure p "Pressure"; + input MassFraction x "Vapour quality"; + output ThermodynamicState state "Thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := setState_ph( + p, + (1 - x)*bubbleEnthalpy( + setSat_pX(p,{1})) + + x*dewEnthalpy( + setSat_pX(p,{1})), + 2); + annotation(Documentation(info="")); + end setState_px; + + replaceable function setState_Tx + "Return thermodynamic state from temperature and vapour quality" + input Temperature T "Temperature"; + input MassFraction x "Vapour quality"; + output ThermodynamicState state "thermodynamic state record"; + algorithm + assert(nX==1,"This function is not allowed for mixtures."); + state := setState_ph( + saturationPressure_sat( + setSat_TX(T,{1})), + (1 - x)*bubbleEnthalpy( + setSat_TX(T,{1})) + + x*dewEnthalpy( + setSat_TX(T,{1})), + 2); + annotation(Documentation(info="")); + end setState_Tx; + + replaceable function density_ph "Return density from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use density_phX() instead!"); + d := density_phX(p, h, fill(0,0), phase); + annotation(Documentation(info="")); + end density_ph; + + replaceable function specificEnthalpy_dT + "Return specific enthalpy from d and T" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_dX() instead!"); + h := specificEnthalpy(setState_dTX( + d, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end specificEnthalpy_dT; + + replaceable function temperature_ph "Return temperature from p and h" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEnthalpy h "Specific enthalpy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use temperature_phX() instead!"); + T := temperature_phX(p, h, fill(0,0),phase); + annotation(Documentation(info="")); + end temperature_ph; + + replaceable function pressure_dT "Return pressure from d and T" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output AbsolutePressure p "Pressure"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use pressure_dTX() instead!"); + p := pressure(setState_dTX( + d, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end pressure_dT; + + replaceable function specificEnthalpy_ps + "Return specific enthalpy from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_psX() instead!"); + h := specificEnthalpy_psX(p,s,reference_X); + annotation(Documentation(info="")); + end specificEnthalpy_ps; + + replaceable function temperature_ps "Return temperature from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Temperature T "Temperature"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use temperature_psX() instead!"); + T := temperature_psX(p,s,fill(0,0),phase); + annotation(Documentation(info="")); + end temperature_ps; + + replaceable function density_ps "Return density from p and s" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use density_psX() instead!"); + d := density_psX(p, s, fill(0,0), phase); + annotation(Documentation(info="")); + end density_ps; + + replaceable function specificEnthalpy_pT + "Return specific enthalpy from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; + algorithm + assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_pTx() instead!"); + h := specificEnthalpy_pTX(p, T, fill(0,0),phase); + annotation(Documentation(info="")); + end specificEnthalpy_pT; + + replaceable function density_pT "Return density from p and T" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Density d "Density"; + algorithm + d := density( + setState_pTX( + p, + T, + fill(0, 0), + phase)); + annotation(Documentation(info="")); + end density_pT; + +redeclare replaceable function density + input ThermodynamicState state "Thermodynamic state record"; + output Density d; +algorithm + d:=state.d; +end density; + +redeclare replaceable function pressure + input ThermodynamicState state "Thermodynamic state record"; + output AbsolutePressure p; +algorithm + p:=state.p; +end pressure; + +redeclare replaceable function specificEnthalpy + input ThermodynamicState state "Thermodynamic state record"; + output SpecificEnthalpy h; +algorithm + h:=state.h; +end specificEnthalpy; + +redeclare replaceable function specificEntropy + input ThermodynamicState state "Thermodynamic state record"; + output SpecificEntropy s; +algorithm + s:=state.s; +end specificEntropy; + +redeclare replaceable function temperature + input ThermodynamicState state "Thermodynamic state record"; + output Temperature T; +algorithm + T:=state.T; +end temperature; + + replaceable function vapourQuality "Return vapour quality" + input ThermodynamicState state "Thermodynamic state record"; + output MassFraction x "Vapour quality"; + protected + constant SpecificEnthalpy eps = 1e-8; + algorithm + x := min(max((specificEnthalpy(state) - bubbleEnthalpy( + setSat_pX( + pressure(state), state.X)))/(dewEnthalpy( + setSat_pX( + pressure(state), state.X)) - bubbleEnthalpy( + setSat_pX( + pressure(state), state.X)) + eps), 0), 1); + annotation(Documentation(info="")); + end vapourQuality; + + replaceable partial function surfaceTension + "Return surface tension sigma in the two phase region" + extends Modelica.Icons.Function; + input SaturationProperties sat "saturation property record"; + output SurfaceTension sigma "Surface tension sigma in the two phase region"; + annotation(Documentation(info="")); + end surfaceTension; + + annotation(Documentation(info=""), + Documentation(info=" +

PartialMixtureTwoPhaseMedium

+ This is a template for two phase medium of a mixture of substances and is used by REFPROPMedium.
+ It has been created by merging PartialMixtureMedium and PartialTwoPhaseMedium from Modelica.Media.Interfaces.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end PartialMixtureTwoPhaseMediumTwo; diff --git a/Interfaces/PureSubstanceInputChoice.mo b/Interfaces/PureSubstanceInputChoice.mo new file mode 100644 index 0000000..56a5514 --- /dev/null +++ b/Interfaces/PureSubstanceInputChoice.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Interfaces; +type PureSubstanceInputChoice = enumeration( + dT "(d,T) as inputs", + ph "(p,h) as inputs", + ps "(p,s) as inputs", + pT "(p,T) as inputs"); diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo new file mode 100644 index 0000000..d962d1d --- /dev/null +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -0,0 +1,1842 @@ +within REFPROP2Modelica.Interfaces; +partial package REFPROPMixtureTwoPhaseMedium + "Two-phase mixture medium (properties supplied by REFPROP library)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMediumTwo( + mediumName="REFPROP Medium", + final reducedX=true, + final singleState=false, + reference_X=cat( + 1, + fill(0, nX - 1), + {1}), + fluidConstants=rpConstants); + + final constant String fluidnames=StrJoin(substanceNames, "|") + "Merge all substance names to one string for refprop library"; + constant Boolean debugmode=false + "print messages in functions and wrapper library if run from command line"; + constant FluidConstants[nS] rpConstants( + each chemicalFormula="REFPROP Medium", + each structureFormula="REFPROP Medium", + each casRegistryNumber="007", + each iupacName="REFPROP Medium", + each molarMass=0.1, + each criticalTemperature=600, + each criticalPressure=300e5, + each criticalMolarVolume=1, + each acentricFactor=1, + each triplePointTemperature=273.15, + each triplePointPressure=1e5, + each meltingPoint=1, + each normalBoilingPoint=1, + each dipoleMoment=1); + +//import REFPROP2Modelica.Interfaces.MixtureInputChoice; +//constant MixtureInputChoice explicitVars = InputChoice.phX +// "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; + +// inputChoice = explicitVars, +//"mediumName is being checked for consistency at flowports" + partial function partialREFPROP "Declaration of array props" + //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() + extends Modelica.Icons.Function; + protected + Real[18 + 2*nX] props; + String errormsg=StrJoin(fill("xxxx", 64), "") + "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; + end partialREFPROP; + + function getProp_REFPROP + "calls C function with property identifier & returns single property" + input String what2calc; + input String statevars; + input String fluidnames; + input Real[:] props; + input Real statevar1; + input Real statevar2; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + input String errormsg; + // input Integer debug=1; + output Real val; + external"C" val= props_REFPROP( + what2calc, + statevars, + fluidnames, + props, + statevar1, + statevar2, + X, + phase, + REFPROP_PATH, + errormsg, + debugmode); + annotation (Include="#include ", Library="refprop_wrapper"); + end getProp_REFPROP; + + function getProp_REFPROP_check + "wrapper for getProp_REFPROP returning 1 property value with error check" + extends partialREFPROP; + input String what2calc; + input String statevars; + // input String fluidnames; + input Real statevar1; + input Real statevar2; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Real val; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + // Modelica.Utilities.Streams.print("Calc "+what2calc); + val := getProp_REFPROP( + what2calc, + statevars, + fluidnames, + props, + statevar1, + statevar2, + X, + phase, + errormsg) "just passing through"; + // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); + assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + + errormsg + "\n"); + end getProp_REFPROP_check; + + function getSatProp_REFPROP + "calls C function with property identifier & returns single property" + input String what2calc; + input String statevar; + input String fluidnames; + input Real[:] props; + input Real statevarval; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + // input Integer debugmode=1; + external"C" val= satprops_REFPROP( + what2calc, + statevar, + fluidnames, + props, + statevarval, + X, + REFPROP_PATH, + errormsg, + debugmode); + annotation (Include="#include ", Library="refprop_wrapper"); + end getSatProp_REFPROP; + + function getSatProp_REFPROP_check + "wrapper for getSatProp_REFPROP returning 1 property value with error check" + extends partialREFPROP; + input String what2calc; + input String statevar; + // input String fluidnames; + input Real statevarval; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Real val; + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + val := getSatProp_REFPROP( + what2calc, + statevar, + fluidnames, + props, + statevarval, + X, + errormsg) "just passing through"; + //Error string decoding in wrapper-c-function + assert(props[1] == 0 or props[1] == 141, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + + errormsg + "\n"); + if props[1] == 141 then + Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); + val := -999; + end if; + end getSatProp_REFPROP_check; + +redeclare record extends ThermodynamicState + "Adapt this record to the returned values from one REFPROP call." + +// Density d_l "density of liquid phase"; +// Density d_g "density of gaseous phase"; +// MassFraction x "void fraction"; +// SpecificInternalEnergy u "Specific energy"; + +// MolarMass MM_l "Molar Mass of liquid phase"; +// MolarMass MM_g "Molar Mass of gas phase"; +// MassFraction X_l[nX] +// "Composition of liquid phase (Mass fractions in kg/kg)"; +// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; +end ThermodynamicState; + +// redeclare record extends ThermodynamicState +// "a selection of variables that uniquely defines the thermodynamic state" +// /* AbsolutePressure p "Absolute pressure of medium"; +// Temperature T "Temperature of medium"; +// MassFraction X[nX] "Composition (Mass fractions in kg/kg)";*/ +// MolarMass MM "Molar Mass of the whole mixture"; +// Density d(start=300) "density"; +// SpecificEnergy u "Specific energy"; +// SpecificEnthalpy h "Specific enthalpy"; +// SpecificEntropy s "Specific entropy"; +// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; +// Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; +// VelocityOfSound c; +// MolarMass MM_l "Molar Mass of liquid phase"; +// MolarMass MM_g "Molar Mass of gas phase"; +// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; +// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; +// // Real GVF "Gas Void Fraction"; +// end ThermodynamicState; + +// redeclare model extends BaseProperties "Base properties of medium" +// equation +// u = h - p/d +// "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; +// MM = state.molarMass; +// R = Modelica.Constants.R/MM; +// //ph-explicit +// if explicitVars=="ph" or explicitVars=="hp" then +// state = setState_phX(p,h,X,0) " ,fluidnames)"; +// T = temperature_phX(p,h,X) +// "double calculation, but necessary if T is given"; +// // T = state.T "can be used instead"; +// s = specificEntropy_phX(p,h,X) +// "double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// d = density_phX(p,h,X) "double calculation, but necessary if d is given"; +// //d = state.d "can be used instead"; +// elseif explicitVars=="pT" or explicitVars=="Tp" then +// //pT-explicit +// state = setState_pTX(p,T,X,0) ",fluidnames)"; +// h = specificEnthalpy_pTX(p,T,X) +// "double calculation, but necessary if s is given"; +// //h = state.h "can be used instead"; +// s = specificEntropy_pTX(p,T,X) +// "state.s double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// d = density_pTX(p,T,X) +// "state.d double calculation, but necessary if d is given"; +// //d = state.d "can be used instead"; +// elseif explicitVars=="dT" or explicitVars=="Td" then +// //Td-explicit +// state = setState_dTX(d,T,X,0) ",fluidnames)"; +// h = specificEnthalpy_dTX(d,T,X) +// "double calculation, but necessary if s is given"; +// //h = state.h "can be used instead"; +// s = specificEntropy_dTX(d,T,X) +// "state.s double calculation, but necessary if s is given"; +// // s = state.s "can be used instead"; +// p = pressure_dTX(d,T,X) +// "state.d double calculation, but necessary if d is given"; +// // p = state.p "can be used instead"; +// elseif explicitVars=="ps" or explicitVars=="ps" then +// state = setState_psX(p,s,X,0) ",fluidnames)"; +// T = temperature_psX(p,s,X); +// h = specificEnthalpy_psX(p,s,X); +// d = density_psX(p,s,X); +// elseif explicitVars=="pd" or explicitVars=="pd" then +// state = setState_pdX(p,d,X,0) ",fluidnames)"; +// T = temperature_pdX(p,d,X); +// h = specificEnthalpy_pdX(p,d,X); +// s = specificEntropy_pdX(p,d,X); +// elseif explicitVars=="hT" or explicitVars=="Th" then +// state = setState_ThX(T,h,X,0) ",fluidnames)"; +// p = pressure_ThX(T,h,X); +// s = specificEntropy_ThX(T,h,X); +// d = density_ThX(T,h,X); +// elseif explicitVars=="sT" or explicitVars=="Ts" then +// state = setState_TsX(T,s,X,0) ",fluidnames)"; +// p = pressure_TsX(T,s,X); +// h = specificEnthalpy_TsX(T,s,X); +// d = density_TsX(T,s,X); +// elseif explicitVars=="hd" or explicitVars=="hd" then +// state = setState_hdX(h,d,X,0) ",fluidnames)"; +// p = pressure_hdX(h,d,X); +// s = specificEntropy_hdX(h,d,X); +// T = temperature_hdX(h,d,X); +// elseif explicitVars=="hs" or explicitVars=="sh" then +// state = setState_hsX(h,s,X,0) ",fluidnames)"; +// p = pressure_hsX(h,s,X); +// T = temperature_hsX(h,s,X); +// d = density_hsX(h,s,X); +// elseif explicitVars=="sd" or explicitVars=="ds" then +// state = setState_dsX(d,s,X,0) ",fluidnames)"; +// p = pressure_dsX(d,s,X); +// h = specificEnthalpy_dsX(d,s,X); +// T = temperature_dsX(d,s,X); +// end if; +// sat.psat = p; +// sat.Tsat = saturationTemperature(p,X); +// sat.X = X; +// annotation (Documentation(info=" +// +// The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
+// That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
+// Then alle state variables are calculated using the corresponding setstate_XX function.
+// In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
+// Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), +// then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
+// Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: +//

    +//
  • Choose the explicitVars to the combination occurring most often in your model. (The combination dT might be favorable, because it is used by REFPROP's internal algorithm.)
  • +//
  • if you are sure, that it won't be needed, in BaseProperties replace explicit calculation of T/s/d/h with definition as state (commented line)
  • +//
+// ")); +// end BaseProperties; + + function setState "Calculates medium properties" + extends partialREFPROP; + input String statevars; + input Real statevar1; + input Real statevar2; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + // Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); + /*protected + Real[16+2*nX] props; + String errormsg=StrJoin(fill("xxxx",64),"") + "Allocating memory, string will be written by C function";*/ + algorithm + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "", + statevars, + fluidnames, + props, + statevar1, + statevar2, + X, + phase, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + /* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; + + If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") + If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") + If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ + state := ThermodynamicState( + p=props[2], + T=props[3], + X=X, + molarMass=props[4], + d=props[5], + h=props[10], + s=props[11], + cv=props[12], + cp=props[13], + a=props[14], + ddhp=props[15], + ddph=props[16], + phase=if (props[8] > 0 and props[8] < 1) then 2 else 1); + // u=props[9], + // d_l=props[6], + // d_g=props[7], + // x=min(max(props[8], 0), 1), + // MM_l=props[17], + // MM_g=props[18], + // X_l=props[19:18 + nX], + // X_g=props[19 + nX:18 + 2*nX], + end setState; + + function setState_dsX "Calculates medium properties from d,s,X" + extends Modelica.Icons.Function; + input Density d "Temperature"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dsX(" + String(d) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "ds", + d, + s, + X, + phase) ",fluidnames)"; + end setState_dsX; + + redeclare replaceable function extends setState_dTX + // input String fluidnames; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dTX(" + String(d) + "," + + String(T) + ",X)..."); + end if; + state := setState( + "dT", + d, + T, + X, + phase) ",fluidnames)"; + end setState_dTX; + + function setState_hsX "Calculates medium properties from h,s,X" + extends Modelica.Icons.Function; + input SpecificEnthalpy h "Enthalpy"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running (" + String(h) + "," + String(s) + + ",X)..."); + end if; + state := setState( + "hs", + h, + s, + X, + phase) ",fluidnames)"; + end setState_hsX; + + function setState_hdX "Calculates medium properties from h,d,X" + extends Modelica.Icons.Function; + input SpecificEnthalpy h "Enthalpy"; + input Density d "Temperature"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_hdX(" + String(h) + "," + + String(d) + ",X)..."); + end if; + state := setState( + "hd", + h, + d, + X, + phase) ",fluidnames)"; + end setState_hdX; + + function setState_pdX "Calculates medium properties from p,d,X" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Density d "Density"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pdX(" + String(p) + "," + + String(d) + ",X)..."); + end if; + state := setState( + "pd", + p, + d, + X, + phase) ",fluidnames)"; + end setState_pdX; + + redeclare replaceable function extends setState_phX + "Calculates medium properties from p,h,X" + // input String fluidnames; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(p) + "," + + String(h) + ",X)..."); + end if; + state := setState( + "ph", + p, + h, + X, + phase) ",fluidnames)"; + end setState_phX; + + function setState_pqX "Calculates medium properties from p,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.AbsolutePressure p "Pressure"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pqX(" + String(p) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "pq", + p, + q, + X, + phase) ",fluidnames)"; + end setState_pqX; + + redeclare replaceable partial function extends setState_psX + "Calculates medium properties from p,s,X" + // input String fluidnames; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_psX(" + String(p) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "ps", + p, + s, + X, + phase) ",fluidnames)"; + end setState_psX; + + redeclare replaceable partial function extends setState_pTX + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_pTX(" + String(p) + "," + + String(T) + ",X)..."); + end if; + state := setState( + "pT", + p, + T, + X, + phase) ",fluidnames)"; + end setState_pTX; + + function setState_ThX "Calculates medium properties from T,h,X" + extends Modelica.Icons.Function; + input Temperature T "Temperature"; + input SpecificEnthalpy h "Enthalpy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_ThX(" + String(T) + "," + + String(h) + ",X)..."); + end if; + state := setState( + "Th", + T, + h, + X, + phase) ",fluidnames)"; + end setState_ThX; + + function setState_TsX "Calculates medium properties from T,s,X" + extends Modelica.Icons.Function; + input Temperature T "Temperature"; + input SpecificEntropy s "Entropy"; + input MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_TsX(" + String(T) + "," + + String(s) + ",X)..."); + end if; + state := setState( + "Ts", + T, + s, + X, + phase) ",fluidnames)"; + end setState_TsX; + + redeclare function extends saturationPressure + algorithm + p := getSatProp_REFPROP_check( + "p", + "T", + T, + X); + end saturationPressure; + + redeclare function extends saturationTemperature + algorithm + T := getSatProp_REFPROP_check( + "T", + "p", + p, + X); + end saturationTemperature; + +// redeclare function extends specificEntropy +// "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" +// algorithm +// s := state.s; +// end specificEntropy; + +// redeclare replaceable function extends density +// "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" +// algorithm +// d := state.d; +// end density; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy" + extends Modelica.Icons.Function; + algorithm + hv := getProp_REFPROP_check( + "h", + "pq", + sat.psat, + 1, + sat.X, + 1); + end dewEnthalpy; + + redeclare function extends dewEntropy "dew curve specific entropy" + extends Modelica.Icons.Function; + algorithm + sv := getProp_REFPROP_check( + "s", + "pq", + sat.psat, + 1, + sat.X, + 1); + end dewEntropy; + + redeclare function extends dewDensity "dew curve specific density" + extends Modelica.Icons.Function; + algorithm + dv := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 1, + sat.X, + 1); + end dewDensity; + + redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" + extends Modelica.Icons.Function; + algorithm + hl := getProp_REFPROP_check( + "h", + "pq", + sat.psat, + 0, + sat.X, + 1); + end bubbleEnthalpy; + + redeclare function extends bubbleEntropy "boiling curve specific entropy" + extends Modelica.Icons.Function; + algorithm + sl := getProp_REFPROP_check( + "s", + "pq", + sat.psat, + 0, + sat.X, + 1); + end bubbleEntropy; + + redeclare function extends bubbleDensity "boiling curve specific density" + extends Modelica.Icons.Function; + algorithm + dl := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 0, + sat.X, + 1); + end bubbleDensity; + + redeclare replaceable function extends molarMass + "Return the molar mass of the mixture" + extends Modelica.Icons.Function; + algorithm + MM := state.molarMass; + end molarMass; + +// redeclare function density_phX +// "calls REFPROP-Wrapper, returns density" +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X +// "composition defined by mass fractions"; +// input FixedPhase phase=0 +// "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.Density d; +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); +// end if; +// // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); +// d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); +// annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), +// p=pressure_hdX(h,d,X,phase))); +// end density_phX; + +// redeclare function temperature_phX +// "calls REFPROP-Wrapper, returns temperature" +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; +// input FixedPhase phase=0 +// "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.Temperature T; +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); +// end if; +// T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); +// annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), +// p=pressure_ThX(T,h,X,phase))); +// end temperature_phX; + + function density_hsX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + d := getProp_REFPROP_check( + "d", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_hdX( + h, + d, + X, + phase), h=specificEnthalpy_dsX( + d, + s, + X, + phase))); + end density_hsX; + + function density_pqX "calls REFPROP-Wrapper, returns specific density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_pqX(" + String(p) + "," + + String(q) + ",X)"); + end if; + d := getProp_REFPROP_check( + "d", + "pq", + p, + q, + X, + phase); + /* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), + q=quality_pdX(p,d,X,phase)));*/ + end density_pqX; + + redeclare function density_psX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_psX(" + String(p) + "," + + String(s) + ",X)"); + end if; + d := getProp_REFPROP_check( + "d", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pdX( + p, + d, + X, + phase), p=pressure_dsX( + d, + s, + X, + phase))); + end density_psX; + + redeclare function density_pTX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + // input String fluidnames; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_pTX(" + String(p) + "," + + String(T) + ",X)..."); + end if; + d := getProp_REFPROP_check( + "d", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_pdX( + p, + d, + X, + phase), p=pressure_dTX( + d, + T, + X, + phase))); + end density_pTX; + + function density_ThX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_ThX(" + String(T) + "," + + String(h) + ",X)"); + end if; + d := getProp_REFPROP_check( + "d", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_dTX( + d, + T, + X, + phase), T=temperature_hdX( + h, + d, + X, + phase))); + end density_ThX; + + function density_TsX "calls REFPROP-Wrapper, returns density" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Density d; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running density_TsX(" + String(T) + "," + + String(s) + ",X)"); + end if; + d := getProp_REFPROP_check( + "d", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_dTX( + d, + T, + X, + phase), T=temperature_dsX( + d, + s, + X, + phase))); + end density_TsX; + + function pressure_dsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_dsX(" + String(d) + "," + + String(s) + ",X)"); + end if; + p := getProp_REFPROP_check( + "p", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pdX( + p, + d, + X, + phase), d=density_psX( + p, + s, + X, + phase))); + end pressure_dsX; + + function pressure_dTX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_dTX(" + String(d) + "," + + String(T) + ",X)"); + end if; + p := getProp_REFPROP_check( + "p", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_pTX( + p, + T, + X, + phase), T=temperature_pdX( + p, + d, + X, + phase))); + end pressure_dTX; + + function pressure_hdX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_hdX(" + String(h) + "," + + String(d) + ",X)"); + end if; + p := getProp_REFPROP_check( + "p", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_pdX( + p, + d, + X, + phase),d=density_phX( + p, + h, + X, + phase))); + end pressure_hdX; + + function pressure_hsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + p := getProp_REFPROP_check( + "p", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_phX( + p, + h, + X, + phase), h=specificEnthalpy_psX( + p, + s, + X, + phase))); + end pressure_hsX; + + function pressure_ThX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_ThX(" + String(T) + "," + + String(h) + ",X)..."); + end if; + p := getProp_REFPROP_check( + "p", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_pTX( + p, + T, + X, + phase), T=temperature_phX( + p, + h, + X, + phase))); + end pressure_ThX; + + function pressure_TqX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + //T=quality_pTX(p,T,X,phase) + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_TqX(" + String(T) + "," + + String(q) + ",X)"); + end if; + p := getProp_REFPROP_check( + "p", + "Tq", + T, + q, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_pqX( + p, + q, + X, + phase))); + end pressure_TqX; + + function pressure_TsX "calls REFPROP-Wrapper, returns pressure" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Pressure p; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running pressure_TsX(" + String(T) + "," + + String(s) + ",X)..."); + end if; + p := getProp_REFPROP_check( + "p", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pTX( + p, + T, + X, + phase), T=temperature_psX( + p, + s, + X, + phase))); + end pressure_TsX; + + function specificEnthalpy_dsX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX(" + String( + d) + "," + String(s) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "ds", fluidnames,d,s,X,phase); + h := getProp_REFPROP_check( + "h", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_hdX( + h, + d, + X, + phase), d=density_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_dsX; + + redeclare function specificEnthalpy_dTX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX(" + String( + d) + "," + String(T) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "dT", fluidnames,d,T,X,phase); + h := getProp_REFPROP_check( + "h", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_ThX( + T, + h, + X, + phase), T=temperature_hdX( + h, + d, + X, + phase))); + end specificEnthalpy_dTX; + + function specificEnthalpy_pdX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX(" + String( + p) + "," + String(d) + ",X)..."); + end if; + // h :=getProp_REFPROP_check("h", "pd", fluidnames,p,d,X,phase); + h := getProp_REFPROP_check( + "h", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_phX( + p, + h, + X, + phase), p=pressure_hdX( + h, + d, + X, + phase))); + end specificEnthalpy_pdX; + + function specificEnthalpy_pqX + "calls REFPROP-Wrapper, returns specific enthalpy" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + // annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX(" + String( + p) + "," + String(q) + ",X)"); + end if; + // h :=getProp_REFPROP_check("h", "pq", fluidnames,p,q,X,phase); + h := getProp_REFPROP_check( + "h", + "pq", + p, + q, + X, + phase); + end specificEnthalpy_pqX; + + redeclare function specificEnthalpy_psX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_psX(" + String( + p) + "," + String(s) + ",X)..."); + end if; + h := getProp_REFPROP_check( + "h", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_phX( + p, + h, + X, + phase), p=pressure_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_psX; + + redeclare function specificEnthalpy_pTX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX(" + String( + p) + "," + String(T) + ",X)..."); + end if; + // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); + h := getProp_REFPROP_check( + "h", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_phX( + p, + h, + X, + phase), p=pressure_ThX( + T, + h, + X, + phase))); + end specificEnthalpy_pTX; + + function specificEnthalpy_TsX + "calls REFPROP-Wrapper, returns specific enthalpy" + //does not extend existing function from PartialMedium because there the algorithm is already defined + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEnthalpy h; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX(" + String( + T) + "," + String(s) + ",X)"); + end if; + h := getProp_REFPROP_check( + "h", + "Ts", + T, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_ThX( + T, + h, + X, + phase), T=temperature_hsX( + h, + s, + X, + phase))); + end specificEnthalpy_TsX; + + function specificEntropy_dTX + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.Temperature T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_dTX(" + String( + d) + "," + String(T) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "dT", + d, + T, + X, + phase); + annotation (LateInline=true, inverse(d=density_TsX( + T, + s, + X, + phase), T=temperature_dsX( + d, + s, + X, + phase))); + end specificEntropy_dTX; + + function specificEntropy_hdX + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_hdX(" + String( + h) + "," + String(d) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_hsX( + h, + s, + X, + phase), h=specificEnthalpy_dsX( + d, + s, + X, + phase))); + end specificEntropy_hdX; + + function specificEntropy_pdX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pdX(" + String( + p) + "," + String(d) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_psX( + p, + s, + X, + phase), p=pressure_dsX( + d, + s, + X, + phase))); + end specificEntropy_pdX; + +// function specificEntropy_phX +// extends Modelica.Icons.Function; +// input Modelica.SIunits.Pressure p; +// input Modelica.SIunits.SpecificEnthalpy h; +// input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; +// // input String fluidnames; +// input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; +// output Modelica.SIunits.SpecificEntropy s; +// /*protected +// Real[14+2*nX] props; +// String errormsg=StrJoin(fill("xxxx",10),"");*/ +// algorithm +// if debugmode then +// Modelica.Utilities.Streams.print("Running specificEntropy_phX(" + String( +// p) + "," + String(h) + ",X)..."); +// // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); +// end if; +// s := getProp_REFPROP_check( +// "s", +// "ph", +// p, +// h, +// X, +// phase); +// annotation (LateInline=true, inverse(h=specificEnthalpy_psX( +// p, +// s, +// X, +// phase), p=pressure_hsX( +// h, +// s, +// X, +// phase))); +// end specificEntropy_phX; + + function specificEntropy_pqX + "calls REFPROP-Wrapper, returns specific entropy" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Real q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + // annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pqX(" + String( + p) + "," + String(q) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "pq", + p, + q, + X, + phase); + end specificEntropy_pqX; + + redeclare function specificEntropy_pTX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_pTX(" + String( + p) + "," + String(T) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "pT", + p, + T, + X, + phase); + annotation (LateInline=true, inverse(T=temperature_psX( + p, + s, + X, + phase), p=pressure_TsX( + T, + s, + X, + phase))); + end specificEntropy_pTX; + + function specificEntropy_ThX + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + // input String fluidnames; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.SpecificEntropy s; + /*protected + Real[14+2*nX] props; + String errormsg=StrJoin(fill("xxxx",10),"");*/ + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running specificEntropy_ThX(" + String( + T) + "," + String(h) + ",X)"); + end if; + s := getProp_REFPROP_check( + "s", + "Th", + T, + h, + X, + phase); + annotation (LateInline=true, inverse(h=specificEnthalpy_TsX( + T, + s, + X, + phase), T=temperature_hsX( + h, + s, + X, + phase))); + end specificEntropy_ThX; + + function temperature_dsX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_dsX(" + String(d) + "," + + String(s) + ",X)"); + end if; + T := getProp_REFPROP_check( + "T", + "ds", + d, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_dTX( + d, + T, + X, + phase), d=density_TsX( + T, + s, + X, + phase))); + end temperature_dsX; + + function temperature_hdX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_hdX(" + String(h) + "," + + String(d) + ",X)"); + end if; + T := getProp_REFPROP_check( + "T", + "hd", + h, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_ThX( + T, + h, + X, + phase), h=specificEnthalpy_dTX( + d, + T, + X, + phase))); + end temperature_hdX; + + function temperature_hsX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.SpecificEnthalpy h; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_hsX(" + String(h) + "," + + String(s) + ",X)"); + end if; + T := getProp_REFPROP_check( + "T", + "hs", + h, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_ThX( + T, + h, + X, + phase), h=specificEnthalpy_TsX( + T, + s, + X, + phase))); + end temperature_hsX; + + function temperature_pdX "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Density d; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + + String(d) + ",X)..."); + end if; + T := getProp_REFPROP_check( + "T", + "pd", + p, + d, + X, + phase); + annotation (LateInline=true, inverse(d=density_pTX( + p, + T, + X, + phase), p=pressure_dTX( + d, + T, + X, + phase))); + end temperature_pdX; + + function temperature_pqX + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input MassFraction q; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + // annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_pqX(" + String(p) + "," + + String(q) + ",X)"); + end if; + T := getProp_REFPROP_check( + "T", + "pq", + p, + q, + X, + phase); + end temperature_pqX; + + redeclare function temperature_psX + "calls REFPROP-Wrapper, returns temperature" + extends Modelica.Icons.Function; + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEntropy s; + input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temperature T; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + + String(s) + ",X)..."); + end if; + T := getProp_REFPROP_check( + "T", + "ps", + p, + s, + X, + phase); + annotation (LateInline=true, inverse(s=specificEntropy_pTX( + p, + T, + X, + phase), p=pressure_TsX( + T, + s, + X, + phase))); + end temperature_psX; + + redeclare function extends thermalConductivity + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running thermalConductivity"); + end if; + lambda := getProp_REFPROP_check( + "l", + "Td", + state.T, + state.d, + state.X, + state.phase); + end thermalConductivity; + +// redeclare function vapourQuality "Return vapour quality" +// input ThermodynamicState state "Thermodynamic state record"; +// output MassFraction x "Vapour quality"; +// algorithm +// x := state.x; +// annotation (Documentation(info="")); +// end vapourQuality; + + redeclare function extends specificHeatCapacityCp + algorithm + cp := state.cp; + end specificHeatCapacityCp; + + redeclare function extends specificHeatCapacityCv + algorithm + cv := state.cv; + end specificHeatCapacityCv; + + redeclare function extends dynamicViscosity + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running dynamicViscosity"); + end if; + eta := getProp_REFPROP_check( + "v", + "Td", + state.T, + state.d, + state.X, + state.phase); + end dynamicViscosity; + + function StrJoin "Converts an Array of Strings into a string separated by |" + input String[:] s_in; + input String delimiter; + output String s_out; + algorithm + s_out := s_in[1]; + for i in 2:size(s_in, 1) loop + s_out := s_out + delimiter + s_in[i]; + end for; + end StrJoin; + annotation (Documentation(info=" +

+REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. +It can be used to model two-phase mixtures of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. +

+

+All files in this library, including the C source files are released under the Modelica License 2. +

+

Installation

+The installation basically consists in copying 2 files and changing one line in this package: +
    +
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. + So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). + Make sure you mask the backslashes. It should look something like +
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • +
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • +
+This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. + +

+

Usage

+As it is based on Modelica.Media, the usage is little different from the usage of the two-phase water model:
+Create an instance of REFPROPMedium and specify the mixture by passing the names of the medium components (medium names are the names of the .fld files in the +%REFPROP%\\fluids directory): +
+  package Medium = REFPROPMedium (final substanceNames={\"nitrogen\",\"argon\"});
+
+Create an Instance of REFPROPMedium.Baseproperties: +
+  Medium.BaseProperties props;
+
+You can then use the BaseProperties model to define the actual medium composition (via Xi or X), to define the thermodynamic state and calculate the corresponding properties. +
+  props.p = 1e5;
+  props.T = 300;
+  props.Xi = {.8};
+  d = props.d;
+  h = props.h;
+
+

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a +thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. +The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be +calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables +of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function +returning an array. +You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": +

+package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
+
+

+

All calculated values are returned in SI-Units and are mass based. +

+

Verbose mode can be switched on globally by setting the variable debugmode to true. This leads to many status messages from the modelica functions + as well as from the compiled library. The latter only appear are only seen in only seen when the dymola.exe is run directly in the command window. + + +

Details

+ In order to take advantage of REFPROP's capability of calculating two-phase mixtures a new Medium template had to be created by merging + Modelica.Media.Interfaces.PartialMixtureMedium and Modelica.Media.Interfaces.PartialTwoPhaseMedium of the Modelica Standard Library 3.1. + Alternatively, there is a version of this package limited to single-substance fluids (REFPROPMediumPureSubstance) which uses the standard + template Modelica.Media.Interfaces.PartialTwoPhaseMedium. + All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because + explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
+ Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of + Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. +

+ +

+

    +
+

+ + +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +", revisions=" + +")); +end REFPROPMixtureTwoPhaseMedium; diff --git a/Interfaces/package.mo b/Interfaces/package.mo new file mode 100644 index 0000000..85f5c15 --- /dev/null +++ b/Interfaces/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica; +package Interfaces "Interfaces for dummy implementations" + extends Modelica.Icons.InterfacesPackage; +end Interfaces; diff --git a/Interfaces/package.order b/Interfaces/package.order new file mode 100644 index 0000000..048dc0e --- /dev/null +++ b/Interfaces/package.order @@ -0,0 +1,4 @@ +PureSubstanceInputChoice +MixtureInputChoice +REFPROPMixtureTwoPhaseMedium +PartialMixtureTwoPhaseMediumTwo diff --git a/Media/Pentane.mo b/Media/Pentane.mo new file mode 100644 index 0000000..22d21a6 --- /dev/null +++ b/Media/Pentane.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Pentane "Pentane from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"pentane"}); +end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo new file mode 100644 index 0000000..1d03112 --- /dev/null +++ b/Media/R410mix.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); +end R410mix; diff --git a/Media/package.mo b/Media/package.mo new file mode 100644 index 0000000..b0947ed --- /dev/null +++ b/Media/package.mo @@ -0,0 +1,3 @@ +within REFPROP2Modelica; +package Media +end Media; diff --git a/Media/package.order b/Media/package.order new file mode 100644 index 0000000..ca12c9b --- /dev/null +++ b/Media/package.order @@ -0,0 +1,2 @@ +Pentane +R410mix diff --git a/PartialMixtureTwoPhaseMedium/FixedPhase.mo b/PartialMixtureTwoPhaseMedium/FixedPhase.mo deleted file mode 100644 index 3d17485..0000000 --- a/PartialMixtureTwoPhaseMedium/FixedPhase.mo +++ /dev/null @@ -1,3 +0,0 @@ -within MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium; -type FixedPhase = Integer(min=0,max=2) - "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; diff --git a/PartialMixtureTwoPhaseMedium/FluidLimits.mo b/PartialMixtureTwoPhaseMedium/FluidLimits.mo deleted file mode 100644 index 5e3532b..0000000 --- a/PartialMixtureTwoPhaseMedium/FluidLimits.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium; -record FluidLimits "validity limits for fluid model" - extends Modelica.Icons.Record; - Temperature TMIN "minimum temperature"; - Temperature TMAX "maximum temperature"; - Density DMIN "minimum density"; - Density DMAX "maximum density"; - AbsolutePressure PMIN "minimum pressure"; - AbsolutePressure PMAX "maximum pressure"; - SpecificEnthalpy HMIN "minimum enthalpy"; - SpecificEnthalpy HMAX "maximum enthalpy"; - SpecificEntropy SMIN "minimum entropy"; - SpecificEntropy SMAX "maximum entropy"; - annotation(Documentation( - info=" -

The minimum pressure mostly applies to the liquid state only. - The minimum density is also arbitrary, but is reasonable for techical - applications to limit iterations in non-linear systems. The limits in - enthalpy and entropy are used as safeguards in inverse iterations.

- ")); -end FluidLimits; diff --git a/PartialMixtureTwoPhaseMedium/package.mo b/PartialMixtureTwoPhaseMedium/package.mo deleted file mode 100644 index 0b703e1..0000000 --- a/PartialMixtureTwoPhaseMedium/package.mo +++ /dev/null @@ -1,728 +0,0 @@ -within MediaTwoPhaseMixture; -partial package PartialMixtureTwoPhaseMedium "Template class for two phase medium of a mixture of substances " - - - extends Modelica.Media.Interfaces.PartialMixtureMedium; -// constant Boolean smoothModel "true if the (derived) model should not generate state events"; - constant Boolean onePhase = false - "true if the (derived) model should never be called with two-phase inputs"; - - - redeclare replaceable record extends FluidConstants - "extended fluid constants" - /* Temperature criticalTemperature "critical temperature"; - AbsolutePressure criticalPressure "critical pressure"; - MolarVolume criticalMolarVolume "critical molar Volume"; - Real acentricFactor "Pitzer acentric factor"; - Temperature triplePointTemperature "triple point temperature"; - AbsolutePressure triplePointPressure "triple point pressure"; - Temperature meltingPoint "melting point at 101325 Pa"; - Temperature normalBoilingPoint "normal boiling point (at 101325 Pa)"; - DipoleMoment dipoleMoment - "dipole moment of molecule in Debye (1 debye = 3.33564e10-30 C.m)"; - Boolean hasIdealGasHeatCapacity=false - "true if ideal gas heat capacity is available"; - Boolean hasCriticalData=false "true if critical data are known"; - Boolean hasDipoleMoment=false "true if a dipole moment known"; - Boolean hasFundamentalEquation=false "true if a fundamental equation"; - Boolean hasLiquidHeatCapacity=false - "true if liquid heat capacity is available"; - Boolean hasSolidHeatCapacity=false - "true if solid heat capacity is available"; - Boolean hasAccurateViscosityData=false - "true if accurate data for a viscosity function is available"; - Boolean hasAccurateConductivityData=false - "true if accurate data for thermal conductivity is available"; - Boolean hasVapourPressureCurve=false - "true if vapour pressure data, e.g. Antoine coefficents are known"; - Boolean hasAcentricFactor=false "true if Pitzer accentric factor is known"; - SpecificEnthalpy HCRIT0=0.0 - "Critical specific enthalpy of the fundamental equation"; - SpecificEntropy SCRIT0=0.0 - "Critical specific entropy of the fundamental equation"; - SpecificEnthalpy deltah=0.0 - "Difference between specific enthalpy model (h_m) and f.eq. (h_f) (h_m - h_f)"; - SpecificEntropy deltas=0.0 - "Difference between specific enthalpy model (s_m) and f.eq. (s_f) (s_m - s_f)"; - */ - annotation(Documentation(info="")); - end FluidConstants; - -constant FluidConstants[nS] fluidConstants "constant data for the fluid"; - - -redeclare replaceable record extends ThermodynamicState - "Thermodynamic state of two phase medium" - FixedPhase phase(min=0, max=2) - "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - MassFraction X_l[nX] "Mass fraction of NaCl in kg/kg"; - annotation(Documentation(info="")); -//MassFraction X[nX] "Mass fraction of NaCl in kg/kg" -end ThermodynamicState; - - - replaceable record SaturationProperties - "Saturation properties of two phase medium" - extends Modelica.Icons.Record; - AbsolutePressure psat "saturation pressure"; - Temperature Tsat "saturation temperature"; - MassFraction X[nX] "Mass fractions"; - annotation(Documentation(info="")); - end SaturationProperties; - - - redeclare replaceable partial model extends BaseProperties - "Base properties (p, d, T, h, s, u, R, MM, sat) of two phase medium" - // Temperature T(start=300); - Modelica.SIunits.SpecificEntropy s; - SaturationProperties sat "Saturation properties at the medium pressure"; - annotation(Documentation(info="")); - end BaseProperties; - - - replaceable partial function setDewState - "Return the thermodynamic state on the dew line" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation point"; - input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; - output ThermodynamicState state "complete thermodynamic state info"; - annotation(Documentation(info="")); - end setDewState; - - - replaceable partial function setBubbleState - "Return the thermodynamic state on the bubble line" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation point"; - input FixedPhase phase(min = 1, max = 2) = 1 "phase: default is one phase"; - output ThermodynamicState state "complete thermodynamic state info"; - annotation(Documentation(info="")); - end setBubbleState; - - - redeclare replaceable partial function extends setState_dTX - "Return thermodynamic state as function of d, T and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_dTX; - - - redeclare replaceable partial function extends setState_phX - "Return thermodynamic state as function of p, h and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_phX; - - - redeclare replaceable partial function extends setState_psX - "Return thermodynamic state as function of p, s and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_psX; - - - redeclare replaceable partial function extends setState_pTX - "Return thermodynamic state as function of p, T and composition X or Xi" - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - annotation(Documentation(info="")); - end setState_pTX; - - - replaceable function setSat_TX - "Return saturation property record from temperature" - extends Modelica.Icons.Function; - input Temperature T "temperature"; - input MassFraction X[nX] "Mass fractions"; - output SaturationProperties sat "saturation property record"; - algorithm - sat.Tsat := T; - sat.psat := saturationPressure(T,X); - sat.X := X; - annotation(Documentation(info="")); - end setSat_TX; - - - replaceable function setSat_pX - "Return saturation property record from pressure" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - input MassFraction X[nX] "Mass fractions"; - output SaturationProperties sat "saturation property record"; - algorithm - sat.psat := p; - sat.Tsat := saturationTemperature(p,X); - sat.X := X; - annotation(Documentation(info="")); - end setSat_pX; - - - replaceable partial function bubbleEnthalpy - "Return bubble point specific enthalpy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEnthalpy hl - "boiling curve specific enthalpy"; - annotation(Documentation(info="")); - end bubbleEnthalpy; - - - replaceable partial function dewEnthalpy - "Return dew point specific enthalpy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEnthalpy hv "dew curve specific enthalpy"; - annotation(Documentation(info="")); - end dewEnthalpy; - - - replaceable partial function bubbleEntropy - "Return bubble point specific entropy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEntropy sl "boiling curve specific entropy"; - annotation(Documentation(info="")); - end bubbleEntropy; - - - replaceable partial function dewEntropy "Return dew point specific entropy" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Modelica.SIunits.SpecificEntropy sv "dew curve specific entropy"; - annotation(Documentation(info="")); - end dewEntropy; - - - replaceable partial function bubbleDensity "Return bubble point density" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Density dl "boiling curve density"; - annotation(Documentation(info="")); - end bubbleDensity; - - - replaceable partial function dewDensity "Return dew point density" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Density dv "dew curve density"; - annotation(Documentation(info="")); - end dewDensity; - - - replaceable partial function saturationPressure - "Return saturation pressure" - extends Modelica.Icons.Function; - input Temperature T "temperature"; - input MassFraction X[:]={1} "fluid composition as mass fractions"; - output AbsolutePressure p "saturation pressure"; - - annotation(Documentation(info="")); - end saturationPressure; - - - replaceable partial function saturationTemperature - "Return saturation temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - input MassFraction X[:]={1} "fluid composition as mass fractions"; - output Temperature T "saturation temperature"; - - annotation(Documentation(info="")); - end saturationTemperature; - - - replaceable function saturationPressure_sat "Return saturation temperature" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output AbsolutePressure p "saturation pressure"; - algorithm - p := sat.psat; - annotation(Documentation(info="")); - end saturationPressure_sat; - - - replaceable function saturationTemperature_sat - "Return saturation temperature" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Temperature T "saturation temperature"; - algorithm - T := sat.Tsat; - annotation(Documentation(info="")); - end saturationTemperature_sat; - - - replaceable partial function saturationTemperature_derp - "Return derivative of saturation temperature w.r.t. pressure" - extends Modelica.Icons.Function; - input AbsolutePressure p "pressure"; - output Real dTp "derivative of saturation temperature w.r.t. pressure"; - annotation(Documentation(info="")); - end saturationTemperature_derp; - - - replaceable function saturationTemperature_derp_sat - "Return derivative of saturation temperature w.r.t. pressure" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output Real dTp "derivative of saturation temperature w.r.t. pressure"; - algorithm - dTp := saturationTemperature_derp(sat.psat); - annotation(Documentation(info="")); - end saturationTemperature_derp_sat; - - - replaceable partial function surfaceTension - "Return surface tension sigma in the two phase region" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output SurfaceTension sigma "Surface tension sigma in the two phase region"; - annotation(Documentation(info="")); - end surfaceTension; - - /* redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - algorithm - MM := fluidConstants[1].molarMass; - end molarMass;*/ - - - replaceable partial function dBubbleDensity_dPressure - "Return bubble point density derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerDensityByPressure ddldp "boiling curve density derivative"; - annotation(Documentation(info="")); - end dBubbleDensity_dPressure; - - - replaceable partial function dDewDensity_dPressure - "Return dew point density derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerDensityByPressure ddvdp "saturated steam density derivative"; - annotation(Documentation(info="")); - end dDewDensity_dPressure; - - - replaceable partial function dBubbleEnthalpy_dPressure - "Return bubble point specific enthalpy derivative" - extends Modelica.Icons.Function; - input SaturationProperties sat "saturation property record"; - output DerEnthalpyByPressure dhldp - "boiling curve specific enthalpy derivative"; - annotation(Documentation(info="")); - end dBubbleEnthalpy_dPressure; - - - replaceable partial function dDewEnthalpy_dPressure - "Return dew point specific enthalpy derivative" - extends Modelica.Icons.Function; - - input SaturationProperties sat "saturation property record"; - output DerEnthalpyByPressure dhvdp - "saturated steam specific enthalpy derivative"; - annotation(Documentation(info="")); - end dDewEnthalpy_dPressure; - - - redeclare replaceable function specificEnthalpy_pTX - "Return specific enthalpy from pressure, temperature and mass fraction" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "Specific enthalpy at p, T, X"; - algorithm - h := specificEnthalpy(setState_pTX(p,T,X,phase)); - annotation(Documentation(info="")); - end specificEnthalpy_pTX; - - - redeclare replaceable function temperature_phX - "Return temperature from p, h, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - T := temperature(setState_phX(p,h,X,phase)); - annotation(Documentation(info="")); - end temperature_phX; - - - redeclare replaceable function density_phX - "Return density from p, h, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "density"; - algorithm - d := density(setState_phX(p,h,X,phase)); - annotation(Documentation(info="")); - end density_phX; - - - redeclare replaceable function temperature_psX - "Return temperature from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - T := temperature(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end temperature_psX; - - - redeclare replaceable function density_psX - "Return density from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - d := density(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end density_psX; - - - redeclare replaceable function specificEnthalpy_psX - "Return specific enthalpy from p, s, and X or Xi" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - h := specificEnthalpy(setState_psX(p,s,X,phase)); - annotation(Documentation(info="")); - end specificEnthalpy_psX; - - - replaceable function setState_pT "Return thermodynamic state from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_pTX(p,T,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_pT; - - - replaceable function setState_ph "Return thermodynamic state from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_phX(p,h,fill(0, 0),phase); - annotation(Documentation(info="")); - end setState_ph; - - - replaceable function setState_ps "Return thermodynamic state from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_psX(p,s,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_ps; - - - replaceable function setState_dT "Return thermodynamic state from d and T" - extends Modelica.Icons.Function; - input Density d "density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_dTX(d,T,fill(0,0),phase); - annotation(Documentation(info="")); - end setState_dT; - - - replaceable function setState_px - "Return thermodynamic state from pressure and vapour quality" - input AbsolutePressure p "Pressure"; - input MassFraction x "Vapour quality"; - output ThermodynamicState state "Thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_ph( - p, - (1 - x)*bubbleEnthalpy( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_pX(p)) + x* - dewEnthalpy(MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_pX(p)), - 2); - annotation(Documentation(info="")); - end setState_px; - - - replaceable function setState_Tx - "Return thermodynamic state from temperature and vapour quality" - input Temperature T "Temperature"; - input MassFraction x "Vapour quality"; - output ThermodynamicState state "thermodynamic state record"; - algorithm - assert(nX==1,"This function is not allowed for mixtures."); - state := setState_ph( - saturationPressure_sat( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)), - (1 - x)*bubbleEnthalpy( - MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)) + x* - dewEnthalpy(MediaTwoPhaseMixture.PartialMixtureTwoPhaseMedium.setSat_TX(T)), - 2); - annotation(Documentation(info="")); - end setState_Tx; - - - replaceable function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; -protected - constant SpecificEnthalpy eps = 1e-8; - algorithm - x := min(max((specificEnthalpy(state) - bubbleEnthalpy(setSat_pX(pressure(state),state.X))) - /(dewEnthalpy(setSat_pX(pressure(state),state.X)) - bubbleEnthalpy(setSat_pX(pressure(state),state.X)) - + eps), 0), 1); - annotation(Documentation(info="")); - end vapourQuality; - - - replaceable function density_ph "Return density from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use density_phX() instead!"); - d := density_phX(p, h, fill(0,0), phase); - annotation(Documentation(info="")); - end density_ph; - - - replaceable function temperature_ph "Return temperature from p and h" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use temperature_phX() instead!"); - T := temperature_phX(p, h, fill(0,0),phase); - annotation(Documentation(info="")); - end temperature_ph; - - - replaceable function pressure_dT "Return pressure from d and T" - extends Modelica.Icons.Function; - input Density d "Density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output AbsolutePressure p "Pressure"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use pressure_dTX() instead!"); - p := pressure(setState_dTX(d, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end pressure_dT; - - - replaceable function specificEnthalpy_dT - "Return specific enthalpy from d and T" - extends Modelica.Icons.Function; - input Density d "Density"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_dX() instead!"); - h := specificEnthalpy(setState_dTX(d, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end specificEnthalpy_dT; - - - replaceable function specificEnthalpy_ps - "Return specific enthalpy from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_psX() instead!"); - h := specificEnthalpy_psX(p,s,reference_X); - annotation(Documentation(info="")); - end specificEnthalpy_ps; - - - replaceable function temperature_ps "Return temperature from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Temperature T "Temperature"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use temperature_psX() instead!"); - T := temperature_psX(p,s,fill(0,0),phase); - annotation(Documentation(info="")); - end temperature_ps; - - - replaceable function density_ps "Return density from p and s" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use density_psX() instead!"); - d := density_psX(p, s, fill(0,0), phase); - annotation(Documentation(info="")); - end density_ps; - - - replaceable function specificEnthalpy_pT - "Return specific enthalpy from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; - algorithm - assert(nX==1,"This function is not allowed for mixtures. Use specificEnthalpy_pTx() instead!"); - h := specificEnthalpy_pTX(p, T, fill(0,0),phase); - annotation(Documentation(info="")); - end specificEnthalpy_pT; - - - replaceable function density_pT "Return density from p and T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Density d "Density"; - algorithm - d := density(setState_pTX(p, T, fill(0,0),phase)); - annotation(Documentation(info="")); - end density_pT; - - -replaceable function specificEnthalpy_dTX - "Return specific enthalpy from d, T, and X or Xi" - extends Modelica.Icons.Function; - input Density d "Pressure"; - input Temperature T "Specific entropy"; - input MassFraction X[nX] "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := specificEnthalpy(setState_dTX(d,T,X,phase)); - -annotation(Documentation(info="")); -end specificEnthalpy_dTX; - - -redeclare replaceable function pressure - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Pressure p; -algorithm - p:=state.p; -end pressure; - - -redeclare replaceable function specificEnthalpy - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - h:=state.h; -end specificEnthalpy; - - -replaceable function density_liq - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Density d_l; -algorithm - d_l:=state.d_l; -end density_liq; - - - replaceable function dynamicViscosity_liq "Viscosity of liquid phase" - // extends dynamicViscosity; Warum funzt das nicht? Er sagt "multiple algorithms" - extends Modelica.Icons.Function; - input ThermodynamicState state "thermodynamic state record"; - output DynamicViscosity eta "Dynamic viscosity"; - /*protected - Modelica.SIunits.Pressure p_sat = max(state.p,saturationPressure(state.T, {1})); - ThermodynamicState state_l=state "liquid state"; -algorithm - state_l.d:=state.d_l; - state_l.p:=p_sat; - eta := dynamicViscosity(state_l); -// eta := Modelica.Media.Water.IF97_Utilities.dynamicViscosity(state.d_l, state.T, p_sat, 1); -// Modelica.Utilities.Streams.print(String(p_sat)); -*/ - end dynamicViscosity_liq; - - - replaceable function dynamicViscosity_gas "Viscosity of liquid phase" - // extends dynamicViscosity; Warum funzt das nicht? Er sagt "multiple algorithms" - extends Modelica.Icons.Function; - input ThermodynamicState state "thermodynamic state record"; - output DynamicViscosity eta "Dynamic viscosity"; - /*protected - Modelica.SIunits.Pressure p_sat = min(state.p,saturationPressure(state.T, {1})); - ThermodynamicState state_g=state "gaseous state"; -algorithm - state_g.d:=state.d_g; - state_g.p:=p_sat; - eta := dynamicViscosity(state_g); - */ - // eta := Modelica.Media.Water.IF97_Utilities.dynamicViscosity(state.d_g, state.T, p_sat, 1); - end dynamicViscosity_gas; - - - annotation (Documentation(info=" -

PartialMixtureTwoPhaseMedium

- This is a template for two phase medium of a mixture of substances and is used by REFPROPMedium.
- It has been created by merging PartialMixtureMedium and PartialTwoPhaseMedium from Modelica.Media.Interfaces.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -"), uses(Modelica(version="3.1"))); -end PartialMixtureTwoPhaseMedium; diff --git a/PartialMixtureTwoPhaseMedium/package.order b/PartialMixtureTwoPhaseMedium/package.order deleted file mode 100644 index 6ccc947..0000000 --- a/PartialMixtureTwoPhaseMedium/package.order +++ /dev/null @@ -1,61 +0,0 @@ -onePhase -FluidLimits -FluidConstants -fluidConstants -ThermodynamicState -SaturationProperties -FixedPhase -BaseProperties -setDewState -setBubbleState -setState_dTX -setState_phX -setState_psX -setState_pTX -setSat_TX -setSat_pX -bubbleEnthalpy -dewEnthalpy -bubbleEntropy -dewEntropy -bubbleDensity -dewDensity -saturationPressure -saturationTemperature -saturationPressure_sat -saturationTemperature_sat -saturationTemperature_derp -saturationTemperature_derp_sat -surfaceTension -dBubbleDensity_dPressure -dDewDensity_dPressure -dBubbleEnthalpy_dPressure -dDewEnthalpy_dPressure -specificEnthalpy_pTX -temperature_phX -density_phX -temperature_psX -density_psX -specificEnthalpy_psX -setState_pT -setState_ph -setState_ps -setState_dT -setState_px -setState_Tx -vapourQuality -density_ph -temperature_ph -pressure_dT -specificEnthalpy_dT -specificEnthalpy_ps -temperature_ps -density_ps -specificEnthalpy_pT -density_pT -specificEnthalpy_dTX -pressure -specificEnthalpy -density_liq -dynamicViscosity_liq -dynamicViscosity_gas diff --git a/REFPROPMedium/StrJoin.mo b/REFPROPMedium/StrJoin.mo deleted file mode 100644 index f44713b..0000000 --- a/REFPROPMedium/StrJoin.mo +++ /dev/null @@ -1,11 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function StrJoin "Converts an Array of Strings into a string separated by |" - input String[:] s_in; - input String delimiter; - output String s_out; -algorithm - s_out :=s_in[1]; - for i in 2:size(s_in,1) loop - s_out :=s_out + delimiter + s_in[i]; - end for; -end StrJoin; diff --git a/REFPROPMedium/density_ThX.mo b/REFPROPMedium/density_ThX.mo deleted file mode 100644 index ccfa89b..0000000 --- a/REFPROPMedium/density_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_ThX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_ThX("+String(T)+","+String(h)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_dTX(d,T,X,phase), - T=temperature_hdX(h,d,X,phase))); -end density_ThX; diff --git a/REFPROPMedium/density_TsX.mo b/REFPROPMedium/density_TsX.mo deleted file mode 100644 index 5b9267e..0000000 --- a/REFPROPMedium/density_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_TsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_TsX("+String(T)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - T=temperature_dsX(d,s,X,phase))); -end density_TsX; diff --git a/REFPROPMedium/density_hsX.mo b/REFPROPMedium/density_hsX.mo deleted file mode 100644 index 54ac0a2..0000000 --- a/REFPROPMedium/density_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_hsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_hsX("+String(h)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end density_hsX; diff --git a/REFPROPMedium/density_pqX.mo b/REFPROPMedium/density_pqX.mo deleted file mode 100644 index 2d4338d..0000000 --- a/REFPROPMedium/density_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function density_pqX "calls REFPROP-Wrapper, returns specific density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pqX("+String(p)+","+String(q)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "pq",p,q,X,phase); -/* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), - q=quality_pdX(p,d,X,phase)));*/ -end density_pqX; diff --git a/REFPROPMedium/getProp_REFPROP.mo b/REFPROPMedium/getProp_REFPROP.mo deleted file mode 100644 index ade4a0a..0000000 --- a/REFPROPMedium/getProp_REFPROP.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevars; - input String fluidnames; - input Real[:] props; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - input String errormsg; -// input Integer debug=1; - output Real val; - - external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); - -annotation (Include="#include ", Library="refprop_wrapper"); -end getProp_REFPROP; diff --git a/REFPROPMedium/getProp_REFPROP_check.mo b/REFPROPMedium/getProp_REFPROP_check.mo deleted file mode 100644 index 35a2e02..0000000 --- a/REFPROPMedium/getProp_REFPROP_check.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getProp_REFPROP_check - "wrapper for getProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevars; -// input String fluidnames; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - -// Modelica.Utilities.Streams.print("Calc "+what2calc); - val :=getProp_REFPROP(what2calc,statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg) - "just passing through"; - -// Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); - assert(props[1]==0,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - -end getProp_REFPROP_check; diff --git a/REFPROPMedium/getSatProp_REFPROP.mo b/REFPROPMedium/getSatProp_REFPROP.mo deleted file mode 100644 index 7e59f44..0000000 --- a/REFPROPMedium/getSatProp_REFPROP.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getSatProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevar; - input String fluidnames; - input Real[:] props; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input String errormsg; - output Real val; -// input Integer debugmode=1; - - external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - - annotation (Include="#include ", Library="refprop_wrapper"); -end getSatProp_REFPROP; diff --git a/REFPROPMedium/getSatProp_REFPROP_check.mo b/REFPROPMedium/getSatProp_REFPROP_check.mo deleted file mode 100644 index d3f6441..0000000 --- a/REFPROPMedium/getSatProp_REFPROP_check.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function getSatProp_REFPROP_check - "wrapper for getSatProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevar; -// input String fluidnames; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - val :=getSatProp_REFPROP(what2calc,statevar,fluidnames,props,statevarval,X,errormsg) - "just passing through"; -//Error string decoding in wrapper-c-function - assert(props[1]==0 or props[1]==141,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - if props[1]==141 then - Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); - val :=-999; - end if; -end getSatProp_REFPROP_check; diff --git a/REFPROPMedium/package.mo b/REFPROPMedium/package.mo deleted file mode 100644 index 6c88db5..0000000 --- a/REFPROPMedium/package.mo +++ /dev/null @@ -1,597 +0,0 @@ -within MediaTwoPhaseMixture; -package REFPROPMedium "Two Phase Mixture Medium whose property functions are supplied by REFPROPR (via wrapper for refprop.dll)" -constant Boolean debugmode = false - "print messages in functions and in refpropwrapper.lib (to see the latter, start dymosim.exe in command window)"; - -constant String explicitVars = "ph" - "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; -final constant String fluidnames= StrJoin(substanceNames,"|"); - - -extends PartialMixtureTwoPhaseMedium( - mediumName="REFPROP Medium", - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = rpConstants); -//"mediumName is being checked for consistency at flowports" - - constant FluidConstants[nS] rpConstants( - each chemicalFormula = "REFPROP Medium", - each structureFormula="REFPROP Medium", - each casRegistryNumber="007", - each iupacName="REFPROP Medium", - each molarMass=0.1, - each criticalTemperature = 600, - each criticalPressure = 300e5, - each criticalMolarVolume = 1, - each acentricFactor = 1, - each triplePointTemperature = 273.15, - each triplePointPressure = 1e5, - each meltingPoint = 1, - each normalBoilingPoint = 1, - each dipoleMoment = 1); - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T "Temperature of medium"; - MassFraction X[nX] "Composition (Mass fractions in kg/kg)";*/ - MolarMass MM "Molar Mass of the whole mixture"; - Density d(start=300) "density"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real x "vapor quality on a mass basis [mass vapor/total mass]"; - SpecificEnergy u "Specific energy"; - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; - Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; - VelocityOfSound c; - MolarMass MM_l "Molar Mass of liquid phase"; - MolarMass MM_g "Molar Mass of gas phase"; - MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; - MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; -// Real GVF "Gas Void Fraction"; -end ThermodynamicState; - - - redeclare model extends BaseProperties "Base properties of medium" - - equation - u = h - p/d - "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; - MM = state.MM; - R = 1 "Modelica.Constants.R/MM"; - - //ph-explicit - if explicitVars=="ph" or explicitVars=="hp" then - state = setState_phX(p,h,X,0) " ,fluidnames)"; - T = temperature_phX(p,h,X) - "double calculation, but necessary if T is given"; - // T = state.T "can be used instead"; - - s = specificEntropy_phX(p,h,X) - "double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_phX(p,h,X) "double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="pT" or explicitVars=="Tp" then - //pT-explicit - state = setState_pTX(p,T,X,0) ",fluidnames)"; - h = specificEnthalpy_pTX(p,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_pTX(p,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_pTX(p,T,X) - "state.d double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="dT" or explicitVars=="Td" then - //Td-explicit - state = setState_dTX(d,T,X,0) ",fluidnames)"; - h = specificEnthalpy_dTX(d,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_dTX(d,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - p = pressure_dTX(d,T,X) - "state.d double calculation, but necessary if d is given"; - // p = state.p "can be used instead"; - elseif explicitVars=="ps" or explicitVars=="ps" then - state = setState_psX(p,s,X,0) ",fluidnames)"; - T = temperature_psX(p,s,X); - h = specificEnthalpy_psX(p,s,X); - d = density_psX(p,s,X); - elseif explicitVars=="pd" or explicitVars=="pd" then - state = setState_pdX(p,d,X,0) ",fluidnames)"; - T = temperature_pdX(p,d,X); - h = specificEnthalpy_pdX(p,d,X); - s = specificEntropy_pdX(p,d,X); - elseif explicitVars=="hT" or explicitVars=="Th" then - state = setState_ThX(T,h,X,0) ",fluidnames)"; - p = pressure_ThX(T,h,X); - s = specificEntropy_ThX(T,h,X); - d = density_ThX(T,h,X); - elseif explicitVars=="sT" or explicitVars=="Ts" then - state = setState_TsX(T,s,X,0) ",fluidnames)"; - p = pressure_TsX(T,s,X); - h = specificEnthalpy_TsX(T,s,X); - d = density_TsX(T,s,X); - elseif explicitVars=="hd" or explicitVars=="hd" then - state = setState_hdX(h,d,X,0) ",fluidnames)"; - p = pressure_hdX(h,d,X); - s = specificEntropy_hdX(h,d,X); - T = temperature_hdX(h,d,X); - elseif explicitVars=="hs" or explicitVars=="sh" then - state = setState_hsX(h,s,X,0) ",fluidnames)"; - p = pressure_hsX(h,s,X); - T = temperature_hsX(h,s,X); - d = density_hsX(h,s,X); - elseif explicitVars=="sd" or explicitVars=="ds" then - state = setState_dsX(d,s,X,0) ",fluidnames)"; - p = pressure_dsX(d,s,X); - h = specificEnthalpy_dsX(d,s,X); - T = temperature_dsX(d,s,X); - end if; - - sat.psat = p; - sat.Tsat = saturationTemperature(p,X); - sat.X = X; - annotation (Documentation(info=" - - The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
- That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
- Then alle state variables are calculated using the corresponding setstate_XX function.
- In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
- Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), - then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
- Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: -

    -
  • Choose the explicitVars to the combination occurring most often in your model. (The combination dT might be favorable, because it is used by REFPROP's internal algorithm.)
  • -
  • if you are sure, that it won't be needed, in BaseProperties replace explicit calculation of T/s/d/h with definition as state (commented line)
  • -
- ")); - end BaseProperties; - - -redeclare function extends saturationPressure -// extends Modelica.Icons.Function; -algorithm -// p := getSatProp_REFPROP_check("p", "T", fluidnames,T,X); - p := getSatProp_REFPROP_check("p", "T", T,X); -end saturationPressure; - - -redeclare function extends saturationTemperature -// extends Modelica.Icons.Function; -algorithm -// T := getSatProp_REFPROP_check("T", "p", fluidnames,p,X); - T := getSatProp_REFPROP_check("T", "p", p,X); -end saturationTemperature; - - - redeclare function extends specificEntropy - "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - s := state.s; - end specificEntropy; - - - redeclare replaceable function extends density - "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - d := state.d; - end density; - - -redeclare function extends dewEnthalpy "dew curve specific enthalpy" - extends Modelica.Icons.Function; -algorithm - hv := getProp_REFPROP_check("h", "pq", sat.psat,1,sat.X,1); -end dewEnthalpy; - - - redeclare function extends dewEntropy "dew curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sv := getProp_REFPROP_check("s", "pq", sat.psat,1,sat.X,1); - end dewEntropy; - - - redeclare function extends dewDensity "dew curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dv := getProp_REFPROP_check("d", "pq", sat.psat,1,sat.X,1); - end dewDensity; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - extends Modelica.Icons.Function; - algorithm - hl := getProp_REFPROP_check("h", "pq", sat.psat,0,sat.X,1); - end bubbleEnthalpy; - - - redeclare function extends bubbleEntropy - "boiling curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sl := getProp_REFPROP_check("s", "pq", sat.psat,0,sat.X,1); - end bubbleEntropy; - - - redeclare function extends bubbleDensity - "boiling curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dl := getProp_REFPROP_check("d", "pq", sat.psat,0,sat.X,1); - end bubbleDensity; - - -redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - extends Modelica.Icons.Function; -algorithm - MM:=state.MM; -end molarMass; - - -redeclare replaceable partial function extends setState_phX - "Calculates medium properties from p,h,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX("+String(p)+","+String(h)+",X)..."); - end if; - state := setState("ph",p,h,X,phase) ",fluidnames)"; -end setState_phX; - - - redeclare function density_phX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X - "composition defined by mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); - end if; - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), - p=pressure_hdX(h,d,X,phase))); - end density_phX; - - - redeclare function temperature_phX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - p=pressure_ThX(T,h,X,phase))); - end temperature_phX; - - -redeclare replaceable partial function extends setState_pTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pTX("+String(p)+","+String(T)+",X)..."); - end if; - state := setState("pT",p,T,X,phase) ",fluidnames)"; -end setState_pTX; - - - redeclare function density_pTX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - // input String fluidnames; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pTX("+String(p)+","+String(T)+",X)..."); - end if; - d :=getProp_REFPROP_check("d", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_pdX(p,d,X,phase), - p=pressure_dTX(d,T,X,phase))); - end density_pTX; - - - redeclare function specificEnthalpy_pTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX("+String(p)+","+String(T)+",X)..."); - end if; - // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); - h :=getProp_REFPROP_check("h", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase), - p=pressure_ThX(T,h,X,phase))); - end specificEnthalpy_pTX; - - - redeclare function specificEntropy_pTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pTX("+String(p)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_psX(p,s,X,phase), - p=pressure_TsX(T,s,X,phase))); - end specificEntropy_pTX; - - -redeclare replaceable partial function extends setState_psX - "Calculates medium properties from p,s,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_psX("+String(p)+","+String(s)+",X)..."); - end if; - state := setState("ps",p,s,X,phase) ",fluidnames)"; -end setState_psX; - - - redeclare function temperature_psX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(s)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pTX(p,T,X,phase), - p=pressure_TsX(T,s,X,phase))); - end temperature_psX; - - - redeclare function specificEnthalpy_psX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_psX("+String(p)+","+String(s)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - p=pressure_hsX(h,s,X,phase))); - end specificEnthalpy_psX; - - - redeclare function density_psX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_psX("+String(p)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - p=pressure_dsX(d,s,X,phase))); - end density_psX; - - -redeclare replaceable partial function extends setState_dTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX("+String(d)+","+String(T)+",X)..."); - end if; - state := setState("dT",d,T,X,phase) ",fluidnames)"; -end setState_dTX; - - - redeclare function specificEnthalpy_dTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX("+String(d)+","+String(T)+",X)"); - end if; - // h :=getProp_REFPROP_check("h", "dT", fluidnames,d,T,X,phase); - h :=getProp_REFPROP_check("h", "dT", d,T,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - T=temperature_hdX(h,d,X,phase))); - end specificEnthalpy_dTX; - - -redeclare function extends dynamicViscosity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running dynamicViscosity"); - end if; - eta := getProp_REFPROP_check("v", "Td",state.T,state.d,state.X,state.phase); -end dynamicViscosity; - - -redeclare function extends thermalConductivity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running thermalConductivity"); - end if; - lambda := getProp_REFPROP_check("l", "Td",state.T,state.d,state.X,state.phase); -end thermalConductivity; - - - redeclare function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; - algorithm - x := state.x; - annotation(Documentation(info="")); - end vapourQuality; - - - redeclare function extends specificHeatCapacityCp - - algorithm - cp:=state.cp; - end specificHeatCapacityCp; - - - redeclare function extends specificHeatCapacityCv - - algorithm - cv:=state.cv; - end specificHeatCapacityCv; - - - annotation (Documentation(info=" -

-REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. -It can be used to model two-phase mixtures of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. -

-

-All files in this library, including the C source files are released under the Modelica License 2. -

-

Installation

-The installation basically consists in copying 2 files and changing one line in this package: -
    -
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. - So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). - Make sure you mask the backslashes. It should look something like -
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • -
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • -
-This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. - -

-

Usage

-As it is based on Modelica.Media, the usage is little different from the usage of the two-phase water model:
-Create an instance of REFPROPMedium and specify the mixture by passing the names of the medium components (medium names are the names of the .fld files in the -%REFPROP%\\fluids directory): -
-  package Medium = REFPROPMedium (final substanceNames={\"nitrogen\",\"argon\"});
-
-Create an Instance of REFPROPMedium.Baseproperties: -
-  Medium.BaseProperties props;
-
-You can then use the BaseProperties model to define the actual medium composition (via Xi or X), to define the thermodynamic state and calculate the corresponding properties. -
-  props.p = 1e5;
-  props.T = 300;
-  props.Xi = {.8};
-  d = props.d;
-  h = props.h;
-
-

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a -thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. -The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be -calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables -of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function -returning an array. -You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": -

-package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
-
-

-

All calculated values are returned in SI-Units and are mass based. -

-

Verbose mode can be switched on globally by setting the variable debugmode to true. This leads to many status messages from the modelica functions - as well as from the compiled library. The latter only appear are only seen in only seen when the dymola.exe is run directly in the command window. - - -

Details

- In order to take advantage of REFPROP's capability of calculating two-phase mixtures a new Medium template had to be created by merging - Modelica.Media.Interfaces.PartialMixtureMedium and Modelica.Media.Interfaces.PartialTwoPhaseMedium of the Modelica Standard Library 3.1. - Alternatively, there is a version of this package limited to single-substance fluids (REFPROPMediumPureSubstance) which uses the standard - template Modelica.Media.Interfaces.PartialTwoPhaseMedium. - All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because - explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
- Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of - Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. -

- -

-

    -
-

- - -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -"), uses(Modelica(version="3.2"))); -end REFPROPMedium; diff --git a/REFPROPMedium/package.order b/REFPROPMedium/package.order deleted file mode 100644 index 95f6c45..0000000 --- a/REFPROPMedium/package.order +++ /dev/null @@ -1,75 +0,0 @@ -debugmode -explicitVars -fluidnames -rpConstants -ThermodynamicState -BaseProperties -StrJoin -partialREFPROP -getSatProp_REFPROP_check -getSatProp_REFPROP -saturationPressure -saturationTemperature -getProp_REFPROP_check -getProp_REFPROP -setState -specificEntropy -density -dewEnthalpy -dewEntropy -dewDensity -bubbleEnthalpy -bubbleEntropy -bubbleDensity -molarMass -setState_phX -density_phX -temperature_phX -specificEntropy_phX -setState_pTX -density_pTX -specificEnthalpy_pTX -specificEntropy_pTX -setState_psX -temperature_psX -specificEnthalpy_psX -density_psX -setState_pdX -temperature_pdX -specificEnthalpy_pdX -specificEntropy_pdX -setState_ThX -pressure_ThX -density_ThX -specificEntropy_ThX -setState_dTX -pressure_dTX -specificEnthalpy_dTX -specificEntropy_dTX -setState_TsX -pressure_TsX -specificEnthalpy_TsX -density_TsX -setState_hdX -pressure_hdX -temperature_hdX -specificEntropy_hdX -setState_hsX -pressure_hsX -temperature_hsX -density_hsX -setState_dsX -pressure_dsX -temperature_dsX -specificEnthalpy_dsX -setState_pqX -density_pqX -pressure_TqX -specificEnthalpy_pqX -specificEntropy_pqX -temperature_pqX -dynamicViscosity -thermalConductivity -vapourQuality -specificHeatCapacityCp -specificHeatCapacityCv diff --git a/REFPROPMedium/partialREFPROP.mo b/REFPROPMedium/partialREFPROP.mo deleted file mode 100644 index e63fed0..0000000 --- a/REFPROPMedium/partialREFPROP.mo +++ /dev/null @@ -1,9 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -partial function partialREFPROP "Declaration of array props" -//used by getSatProp_REFPROP_check() and getProp_REFPROP_check() - extends Modelica.Icons.Function; -protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; -end partialREFPROP; diff --git a/REFPROPMedium/pressure_ThX.mo b/REFPROPMedium/pressure_ThX.mo deleted file mode 100644 index 110c086..0000000 --- a/REFPROPMedium/pressure_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_ThX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_ThX("+String(T)+","+String(h)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - T=temperature_phX(p,h,X,phase))); -end pressure_ThX; diff --git a/REFPROPMedium/pressure_TqX.mo b/REFPROPMedium/pressure_TqX.mo deleted file mode 100644 index 0493d86..0000000 --- a/REFPROPMedium/pressure_TqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_TqX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; - //T=quality_pTX(p,T,X,phase) -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TqX("+String(T)+","+String(q)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "Tq",T,q,X,phase); - annotation(LateInline=true,inverse(T=temperature_pqX(p,q,X,phase))); -end pressure_TqX; diff --git a/REFPROPMedium/pressure_TsX.mo b/REFPROPMedium/pressure_TsX.mo deleted file mode 100644 index 22b56a2..0000000 --- a/REFPROPMedium/pressure_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_TsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TsX("+String(T)+","+String(s)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_pTX(p,T,X,phase), - T=temperature_psX(p,s,X,phase))); -end pressure_TsX; diff --git a/REFPROPMedium/pressure_dTX.mo b/REFPROPMedium/pressure_dTX.mo deleted file mode 100644 index e8664f0..0000000 --- a/REFPROPMedium/pressure_dTX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_dTX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dTX("+String(d)+","+String(T)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_pTX(p,T,X,phase), - T=temperature_pdX(p,d,X,phase))); -end pressure_dTX; diff --git a/REFPROPMedium/pressure_dsX.mo b/REFPROPMedium/pressure_dsX.mo deleted file mode 100644 index c02f8b5..0000000 --- a/REFPROPMedium/pressure_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_dsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dsX("+String(d)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - d=density_psX(p,s,X,phase))); -end pressure_dsX; diff --git a/REFPROPMedium/pressure_hdX.mo b/REFPROPMedium/pressure_hdX.mo deleted file mode 100644 index e35dba0..0000000 --- a/REFPROPMedium/pressure_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_hdX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hdX("+String(h)+","+String(d)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_phX(p,h,X,phase), - h=specificEnthalpy_pdX(p,d,X,phase))); -end pressure_hdX; diff --git a/REFPROPMedium/pressure_hsX.mo b/REFPROPMedium/pressure_hsX.mo deleted file mode 100644 index d7b5ad2..0000000 --- a/REFPROPMedium/pressure_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function pressure_hsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hsX("+String(h)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - h=specificEnthalpy_psX(p,s,X,phase))); -end pressure_hsX; diff --git a/REFPROPMedium/setState.mo b/REFPROPMedium/setState.mo deleted file mode 100644 index 487ee63..0000000 --- a/REFPROPMedium/setState.mo +++ /dev/null @@ -1,45 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState "Calculates medium properties" - extends partialREFPROP; - input String statevars; - input Real statevar1; - input Real statevar2; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -// Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); -/*protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function";*/ - -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - getProp_REFPROP("",statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg); - assert(props[1]==0,"Error in REFPROP wrapper function: "+errormsg +"\n"); -/* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; - - If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") - If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") - If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ - state := ThermodynamicState( p= props[2], - T= props[3], - X= X, - MM= props[4], - d=props[5], - d_l=props[6], - d_g=props[7], - x=min(max(props[8],0),1), - u=props[9], - h=props[10], - s=props[11], - cv=props[12], - cp=props[13], - c=props[14], - MM_l=props[15], - MM_g=props[16], - X_l=props[17:16+nX], - X_g=props[17+nX:16+2*nX], - phase=if (props[8]>0 and props[8]<1) then 2 else 1); -end setState; diff --git a/REFPROPMedium/setState_ThX.mo b/REFPROPMedium/setState_ThX.mo deleted file mode 100644 index 1d180d0..0000000 --- a/REFPROPMedium/setState_ThX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_ThX "Calculates medium properties from T,h,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEnthalpy h "Enthalpy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_ThX("+String(T)+","+String(h)+",X)..."); - end if; - state := setState("Th",T,h,X,phase) ",fluidnames)"; -end setState_ThX; diff --git a/REFPROPMedium/setState_TsX.mo b/REFPROPMedium/setState_TsX.mo deleted file mode 100644 index eca8fb9..0000000 --- a/REFPROPMedium/setState_TsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_TsX "Calculates medium properties from T,s,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_TsX("+String(T)+","+String(s)+",X)..."); - end if; - state := setState("Ts",T,s,X,phase) ",fluidnames)"; -end setState_TsX; diff --git a/REFPROPMedium/setState_dsX.mo b/REFPROPMedium/setState_dsX.mo deleted file mode 100644 index 83781be..0000000 --- a/REFPROPMedium/setState_dsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_dsX "Calculates medium properties from d,s,X" - extends Modelica.Icons.Function; - input Density d "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dsX("+String(d)+","+String(s)+",X)..."); - end if; - state := setState("ds",d,s,X,phase) ",fluidnames)"; -end setState_dsX; diff --git a/REFPROPMedium/setState_hdX.mo b/REFPROPMedium/setState_hdX.mo deleted file mode 100644 index bcadcf4..0000000 --- a/REFPROPMedium/setState_hdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_hdX "Calculates medium properties from h,d,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input Density d "Temperature"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_hdX("+String(h)+","+String(d)+",X)..."); - end if; - state := setState("hd",h,d,X,phase) ",fluidnames)"; -end setState_hdX; diff --git a/REFPROPMedium/setState_hsX.mo b/REFPROPMedium/setState_hsX.mo deleted file mode 100644 index 0fa1127..0000000 --- a/REFPROPMedium/setState_hsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_hsX "Calculates medium properties from h,s,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running ("+String(h)+","+String(s)+",X)..."); - end if; - state := setState("hs",h,s,X,phase) ",fluidnames)"; -end setState_hsX; diff --git a/REFPROPMedium/setState_pdX.mo b/REFPROPMedium/setState_pdX.mo deleted file mode 100644 index 0dafcda..0000000 --- a/REFPROPMedium/setState_pdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_pdX "Calculates medium properties from p,d,X" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Density d "Density"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pdX("+String(p)+","+String(d)+",X)..."); - end if; - state := setState("pd",p,d,X,phase) ",fluidnames)"; -end setState_pdX; diff --git a/REFPROPMedium/setState_pqX.mo b/REFPROPMedium/setState_pqX.mo deleted file mode 100644 index 5199d57..0000000 --- a/REFPROPMedium/setState_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function setState_pqX "Calculates medium properties from p,q,X" - extends Modelica.Icons.Function; - input Modelica.SIunits.AbsolutePressure p "Pressure"; - input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pqX("+String(p)+","+String(q)+",X)..."); - end if; - state := setState("pq",p,q,X,phase) ",fluidnames)"; -end setState_pqX; diff --git a/REFPROPMedium/specificEnthalpy_TsX.mo b/REFPROPMedium/specificEnthalpy_TsX.mo deleted file mode 100644 index 171e0c7..0000000 --- a/REFPROPMedium/specificEnthalpy_TsX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_TsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX("+String(T)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_ThX(T,h,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEnthalpy_TsX; diff --git a/REFPROPMedium/specificEnthalpy_dsX.mo b/REFPROPMedium/specificEnthalpy_dsX.mo deleted file mode 100644 index 548cd1b..0000000 --- a/REFPROPMedium/specificEnthalpy_dsX.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_dsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX("+String(d)+","+String(s)+",X)"); - end if; -// h :=getProp_REFPROP_check("h", "ds", fluidnames,d,s,X,phase); - h :=getProp_REFPROP_check("h", "ds", d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - d=density_hsX(h,s,X,phase))); -end specificEnthalpy_dsX; diff --git a/REFPROPMedium/specificEnthalpy_pdX.mo b/REFPROPMedium/specificEnthalpy_pdX.mo deleted file mode 100644 index abb5bb6..0000000 --- a/REFPROPMedium/specificEnthalpy_pdX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_pdX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX("+String(p)+","+String(d)+",X)..."); - end if; -// h :=getProp_REFPROP_check("h", "pd", fluidnames,p,d,X,phase); - h :=getProp_REFPROP_check("h", "pd", p,d,X,phase); - annotation(LateInline=true,inverse(d = density_phX(p,h,X,phase), - p=pressure_hdX(h,d,X,phase))); -end specificEnthalpy_pdX; diff --git a/REFPROPMedium/specificEnthalpy_pqX.mo b/REFPROPMedium/specificEnthalpy_pqX.mo deleted file mode 100644 index 4b6abfc..0000000 --- a/REFPROPMedium/specificEnthalpy_pqX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEnthalpy_pqX - "calls REFPROP-Wrapper, returns specific enthalpy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -// annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX("+String(p)+","+String(q)+",X)"); - end if; -// h :=getProp_REFPROP_check("h", "pq", fluidnames,p,q,X,phase); - h :=getProp_REFPROP_check("h", "pq", p,q,X,phase); -end specificEnthalpy_pqX; diff --git a/REFPROPMedium/specificEntropy_ThX.mo b/REFPROPMedium/specificEntropy_ThX.mo deleted file mode 100644 index 168b2a8..0000000 --- a/REFPROPMedium/specificEntropy_ThX.mo +++ /dev/null @@ -1,20 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_ThX - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_ThX("+String(T)+","+String(h)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h = specificEnthalpy_TsX(T,s,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEntropy_ThX; diff --git a/REFPROPMedium/specificEntropy_dTX.mo b/REFPROPMedium/specificEntropy_dTX.mo deleted file mode 100644 index f18a891..0000000 --- a/REFPROPMedium/specificEntropy_dTX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_dTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_dTX("+String(d)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_TsX(T,s,X,phase), - T=temperature_dsX(d,s,X,phase))); -end specificEntropy_dTX; diff --git a/REFPROPMedium/specificEntropy_hdX.mo b/REFPROPMedium/specificEntropy_hdX.mo deleted file mode 100644 index bd4de6f..0000000 --- a/REFPROPMedium/specificEntropy_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_hdX - extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_hdX("+String(h)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_hsX(h,s,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end specificEntropy_hdX; diff --git a/REFPROPMedium/specificEntropy_pdX.mo b/REFPROPMedium/specificEntropy_pdX.mo deleted file mode 100644 index 5401d50..0000000 --- a/REFPROPMedium/specificEntropy_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_pdX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pdX("+String(p)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_psX(p,s,X,phase), - p=pressure_dsX(d,s,X,phase))); -end specificEntropy_pdX; diff --git a/REFPROPMedium/specificEntropy_phX.mo b/REFPROPMedium/specificEntropy_phX.mo deleted file mode 100644 index 61652e1..0000000 --- a/REFPROPMedium/specificEntropy_phX.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_phX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_phX("+String(p)+","+String(h)+",X)..."); - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - end if; - s:=getProp_REFPROP_check("s", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_psX(p,s,X,phase), - p=pressure_hsX(h,s,X,phase))); -end specificEntropy_phX; diff --git a/REFPROPMedium/specificEntropy_pqX.mo b/REFPROPMedium/specificEntropy_pqX.mo deleted file mode 100644 index 5de1d4b..0000000 --- a/REFPROPMedium/specificEntropy_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function specificEntropy_pqX "calls REFPROP-Wrapper, returns specific entropy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -// annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pqX("+String(p)+","+String(q)+",X)"); - end if; - s :=getProp_REFPROP_check("s", "pq",p,q,X,phase); -end specificEntropy_pqX; diff --git a/REFPROPMedium/temperature_dsX.mo b/REFPROPMedium/temperature_dsX.mo deleted file mode 100644 index 5c220fc..0000000 --- a/REFPROPMedium/temperature_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_dsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_dsX("+String(d)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - d=density_TsX(T,s,X,phase))); -end temperature_dsX; diff --git a/REFPROPMedium/temperature_hdX.mo b/REFPROPMedium/temperature_hdX.mo deleted file mode 100644 index debe323..0000000 --- a/REFPROPMedium/temperature_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_hdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hdX("+String(h)+","+String(d)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - h=specificEnthalpy_dTX(d,T,X,phase))); -end temperature_hdX; diff --git a/REFPROPMedium/temperature_hsX.mo b/REFPROPMedium/temperature_hsX.mo deleted file mode 100644 index 4864bb4..0000000 --- a/REFPROPMedium/temperature_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_hsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hsX("+String(h)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_ThX(T,h,X,phase), - h=specificEnthalpy_TsX(T,s,X,phase))); -end temperature_hsX; diff --git a/REFPROPMedium/temperature_pdX.mo b/REFPROPMedium/temperature_pdX.mo deleted file mode 100644 index e03d68b..0000000 --- a/REFPROPMedium/temperature_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_pdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(d)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d=density_pTX(p,T,X,phase), - p=pressure_dTX(d,T,X,phase))); -end temperature_pdX; diff --git a/REFPROPMedium/temperature_pqX.mo b/REFPROPMedium/temperature_pqX.mo deleted file mode 100644 index 98a382a..0000000 --- a/REFPROPMedium/temperature_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMedium; -function temperature_pqX -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input MassFraction q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -// annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_pqX("+String(p)+","+String(q)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "pq",p,q,X,phase); -end temperature_pqX; diff --git a/REFPROPMediumPureSubstance/StrJoin.mo b/REFPROPMediumPureSubstance/StrJoin.mo deleted file mode 100644 index 632a94b..0000000 --- a/REFPROPMediumPureSubstance/StrJoin.mo +++ /dev/null @@ -1,11 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function StrJoin "Converts an Array of Strings into a string separated by |" - input String[:] s_in; - input String delimiter; - output String s_out; -algorithm - s_out :=s_in[1]; - for i in 2:size(s_in,1) loop - s_out :=s_out + delimiter + s_in[i]; - end for; -end StrJoin; diff --git a/REFPROPMediumPureSubstance/density_ThX.mo b/REFPROPMediumPureSubstance/density_ThX.mo deleted file mode 100644 index cbdecc1..0000000 --- a/REFPROPMediumPureSubstance/density_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_ThX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_ThX("+String(T)+","+String(h)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_dTX(d,T,X,phase), - T=temperature_hdX(h,d,X,phase))); -end density_ThX; diff --git a/REFPROPMediumPureSubstance/density_TsX.mo b/REFPROPMediumPureSubstance/density_TsX.mo deleted file mode 100644 index f305235..0000000 --- a/REFPROPMediumPureSubstance/density_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_TsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_TsX("+String(T)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - T=temperature_dsX(d,s,X,phase))); -end density_TsX; diff --git a/REFPROPMediumPureSubstance/density_hsX.mo b/REFPROPMediumPureSubstance/density_hsX.mo deleted file mode 100644 index 812b528..0000000 --- a/REFPROPMediumPureSubstance/density_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_hsX "calls REFPROP-Wrapper, returns density" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_hsX("+String(h)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end density_hsX; diff --git a/REFPROPMediumPureSubstance/density_pqX.mo b/REFPROPMediumPureSubstance/density_pqX.mo deleted file mode 100644 index d493d76..0000000 --- a/REFPROPMediumPureSubstance/density_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function density_pqX "calls REFPROP-Wrapper, returns specific density" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pqX("+String(p)+","+String(q)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "pq",p,q,X,phase); -/* annotation(LateInline=true,inverse(p=pressure_dqX(d,q,X,phase), - q=quality_pdX(p,d,X,phase)));*/ -end density_pqX; diff --git a/REFPROPMediumPureSubstance/getProp_REFPROP.mo b/REFPROPMediumPureSubstance/getProp_REFPROP.mo deleted file mode 100644 index 4e4dc1b..0000000 --- a/REFPROPMediumPureSubstance/getProp_REFPROP.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevars; - input String fluidnames; - input Real[:] props; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - input String errormsg; -// input Integer debug=1; - output Real val; - - external "C" val = props_REFPROP(what2calc, statevars, fluidnames, props, statevar1, statevar2, X, phase, REFPROP_PATH, errormsg, debugmode); - -annotation (Include="#include ", Library="refprop_wrapper"); -end getProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo b/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo deleted file mode 100644 index d8e383f..0000000 --- a/REFPROPMediumPureSubstance/getProp_REFPROP_check.mo +++ /dev/null @@ -1,23 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getProp_REFPROP_check - "wrapper for getProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevars; -// input String fluidnames; - input Real statevar1; - input Real statevar2; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - -// Modelica.Utilities.Streams.print("Calc "+what2calc); - val :=getProp_REFPROP(what2calc,statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg) - "just passing through"; - -// Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); - assert(props[1]==0,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - -end getProp_REFPROP_check; diff --git a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo b/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo deleted file mode 100644 index 3d50d64..0000000 --- a/REFPROPMediumPureSubstance/getSatProp_REFPROP.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getSatProp_REFPROP - "calls C function with property identifier & returns single property" - input String what2calc; - input String statevar; - input String fluidnames; - input Real[:] props; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input String errormsg; - output Real val; -// input Integer debugmode=1; - - external "C" val = satprops_REFPROP(what2calc, statevar, fluidnames, props, statevarval, X, REFPROP_PATH, errormsg, debugmode); - - annotation (Include="#include ", Library="refprop_wrapper"); -end getSatProp_REFPROP; diff --git a/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo b/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo deleted file mode 100644 index 935173d..0000000 --- a/REFPROPMediumPureSubstance/getSatProp_REFPROP_check.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function getSatProp_REFPROP_check - "wrapper for getSatProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; - input String what2calc; - input String statevar; -// input String fluidnames; - input Real statevarval; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - output Real val; -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - val :=getSatProp_REFPROP(what2calc,statevar,fluidnames,props,statevarval,X,errormsg) - "just passing through"; -//Error string decoding in wrapper-c-function - assert(props[1]==0 or props[1]==141,"Errorcode "+String(props[1])+" in REFPROP wrapper function:\n"+errormsg +"\n"); - if props[1]==141 then - Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); - val :=-999; - end if; -end getSatProp_REFPROP_check; diff --git a/REFPROPMediumPureSubstance/package.mo b/REFPROPMediumPureSubstance/package.mo deleted file mode 100644 index e96e706..0000000 --- a/REFPROPMediumPureSubstance/package.mo +++ /dev/null @@ -1,592 +0,0 @@ -within MediaTwoPhaseMixture; -package REFPROPMediumPureSubstance "Two Phase single component two-phase medium whose property functions are supplied by REFPROP (via wrapper for refprop.dll). Extends PartialTwoPhaseMedium." -/*To create this package, REFPROPMedium has been copied and the following things have been changed: --"extends PartialMixtureTwoPhaseMedium" -> "extends Modelica.Media.Interfaces.PartialTwoPhaseMedium" --redeclare record SaturationProperties --added preset X to saturationTemperature() and saturationPressure() --added s and sat in BaseProperties --add p,T,X in ThermodynamicState --for specificEnthalpy_dTX: redeclare function -> function --remove X from ThermodynamicState and SaturationState -*/ - - -redeclare record extends SaturationProperties -// MassFraction X[nX] "Mass fractions"; -end SaturationProperties; - - -redeclare function extends saturationPressure -// extends Modelica.Icons.Function; -// input MassFraction X[:]={1} "fluid composition as mass fractions"; -algorithm - p := getSatProp_REFPROP_check("p", "T",T,reference_X); -end saturationPressure; - - -redeclare function extends saturationTemperature -// extends Modelica.Icons.Function; -// input MassFraction X[:]={1} "fluid composition as mass fractions"; -algorithm - T := getSatProp_REFPROP_check("T", "p",p,reference_X); -end saturationTemperature; -constant Boolean debugmode = false - "print messages in functions and in refpropwrapper.lib (to see the latter, start dymosim.exe in command window)"; - -constant String explicitVars = "ph" - "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; -final constant String fluidnames= StrJoin(substanceNames,"|"); - - -extends Modelica.Media.Interfaces.PartialTwoPhaseMedium( - mediumName="REFPROP Medium", - final singleState=false, - fluidConstants=rpConstants); -//"mediumName is being checked for consistency at flowports" - - constant FluidConstants[nS] rpConstants( - each chemicalFormula = "REFPROP Medium", - each structureFormula="REFPROP Medium", - each casRegistryNumber="007", - each iupacName="REFPROP Medium", - each molarMass=0.1, - each criticalTemperature = 600, - each criticalPressure = 300e5, - each criticalMolarVolume = 1, - each acentricFactor = 1, - each triplePointTemperature = 273.15, - each triplePointPressure = 1e5, - each meltingPoint = 1, - each normalBoilingPoint = 1, - each dipoleMoment = 1); - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" - AbsolutePressure p "Absolute pressure of medium"; - Temperature T "Temperature of medium"; -// MassFraction X[nX] "Composition (Mass fractions in kg/kg)";/**/ - MolarMass MM "Molar Mass of the whole mixture"; - Density d(start=300) "density"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real x "vapor quality on a mass basis [mass vapor/total mass]"; - SpecificEnergy u "Specific energy"; - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; - Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; - VelocityOfSound c; -// MolarMass MM_l "Molar Mass of liquid phase"; -// MolarMass MM_g "Molar Mass of gas phase"; -// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; -// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; -// Real GVF "Gas Void Fraction"; -end ThermodynamicState; - - - redeclare model extends BaseProperties "Base properties of medium" - - Modelica.SIunits.SpecificEntropy s; - SaturationProperties sat "Saturation properties at the medium pressure"; - equation - u = h - p/d - "state.u - calculated anyway by REFPROP, but this way the expression can be derived symbolically"; - MM = state.MM; - R = 1 "Modelica.Constants.R/MM"; - - //ph-explicit - if explicitVars=="ph" or explicitVars=="hp" then - state = setState_phX(p,h,X,0) ",fluidnames)"; - T = temperature_phX(p,h,X) - "double calculation, but necessary if T is given"; - // T = state.T "can be used instead"; - - s = specificEntropy_phX(p,h,X) - "double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_phX(p,h,X) "double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="pT" or explicitVars=="Tp" then - //pT-explicit - state = setState_pTX(p,T,X,0) ",fluidnames)"; - h = specificEnthalpy_pTX(p,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_pTX(p,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - - d = density_pTX(p,T,X) - "state.d double calculation, but necessary if d is given"; - //d = state.d "can be used instead"; - elseif explicitVars=="dT" or explicitVars=="Td" then - //Td-explicit - state = setState_dTX(d,T,X,0) ",fluidnames)"; - h = specificEnthalpy_dTX(d,T,X) - "double calculation, but necessary if s is given"; - //h = state.h "can be used instead"; - - s = specificEntropy_dTX(d,T,X) - "state.s double calculation, but necessary if s is given"; - // s = state.s "can be used instead"; - p = pressure_dTX(d,T,X) - "state.d double calculation, but necessary if d is given"; - // p = state.p "can be used instead"; - elseif explicitVars=="ps" or explicitVars=="ps" then - state = setState_psX(p,s,X,0) ",fluidnames)"; - T = temperature_psX(p,s,X); - h = specificEnthalpy_psX(p,s,X); - d = density_psX(p,s,X); - elseif explicitVars=="pd" or explicitVars=="pd" then - state = setState_pdX(p,d,X,0) ",fluidnames)"; - T = temperature_pdX(p,d,X); - h = specificEnthalpy_pdX(p,d,X); - s = specificEntropy_pdX(p,d,X); - elseif explicitVars=="hT" or explicitVars=="Th" then - state = setState_ThX(T,h,X,0) ",fluidnames)"; - p = pressure_ThX(T,h,X); - s = specificEntropy_ThX(T,h,X); - d = density_ThX(T,h,X); - elseif explicitVars=="sT" or explicitVars=="Ts" then - state = setState_TsX(T,s,X,0) ",fluidnames)"; - p = pressure_TsX(T,s,X); - h = specificEnthalpy_TsX(T,s,X); - d = density_TsX(T,s,X); - elseif explicitVars=="hd" or explicitVars=="hd" then - state = setState_hdX(h,d,X,0) ",fluidnames)"; - p = pressure_hdX(h,d,X); - s = specificEntropy_hdX(h,d,X); - T = temperature_hdX(h,d,X); - elseif explicitVars=="hs" or explicitVars=="sh" then - state = setState_hsX(h,s,X,0) ",fluidnames)"; - p = pressure_hsX(h,s,X); - T = temperature_hsX(h,s,X); - d = density_hsX(h,s,X); - elseif explicitVars=="sd" or explicitVars=="ds" then - state = setState_dsX(d,s,X,0) ",fluidnames)"; - p = pressure_dsX(d,s,X); - h = specificEnthalpy_dsX(d,s,X); - T = temperature_dsX(d,s,X); - end if; - - sat.psat = p; - sat.Tsat = saturationTemperature(p); - // sat.X = X; - annotation (Documentation(info=" - - The baseproperties model is explicit for one set of 2 variables, which can be chosen to be ph, pT, ps, pd, Th, dT, Ts, hd, hs, ds (set explicitVars when calling this package or in package).
- That means, that if only one of these variables is explicitly given, the other one is calculated by inverting its property function.
- Then alle state variables are calculated using the corresponding setstate_XX function.
- In order to avoid numerical inversion by the solver, 3 state variables are set explicitly using their respective property function, which has its inverses defined.
- Example: So for p and h as explicit variables a state given by p and T is calculated by first calculating h with specificEnthalpy_pTX (inverse function of temperature_phX), - then calculating the other variables using setState_phX. s and d, however, are then calculated, although they are already known in the state variable.
- Knowing this, the baseproperty model can be adapted to your calculation needs to decrease computation time: -

    -
  • Choose the explicitVars to the combination occurring most often in your model. (The combination dT might be favorable, because it is used by REFPROP's internal algorithm.)
  • -
  • if you are sure, that it won't be needed, in BaseProperties replace explicit calculation of T/s/d/h with definition as state (commented line)
  • -
- ")); - end BaseProperties; - - - redeclare function extends specificEntropy - "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - s := state.s; - end specificEntropy; - - - redeclare replaceable function extends density - "returns density from state - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" - algorithm - d := state.d; - end density; - - -redeclare function extends dewEnthalpy "dew curve specific enthalpy" - extends Modelica.Icons.Function; -algorithm - hv := getProp_REFPROP_check("h", "pq", sat.psat,1,reference_X,1); -end dewEnthalpy; - - - redeclare function extends dewEntropy "dew curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sv := getProp_REFPROP_check("s", "pq", sat.psat,1,reference_X,1); - end dewEntropy; - - - redeclare function extends dewDensity "dew curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dv := getProp_REFPROP_check("d", "pq", sat.psat,1,reference_X,1); - end dewDensity; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - extends Modelica.Icons.Function; - algorithm - hl := getProp_REFPROP_check("h", "pq", sat.psat,0,reference_X,1); - end bubbleEnthalpy; - - - redeclare function extends bubbleEntropy - "boiling curve specific entropy of water" - extends Modelica.Icons.Function; - algorithm - sl := getProp_REFPROP_check("s", "pq", sat.psat,0,reference_X,1); - end bubbleEntropy; - - - redeclare function extends bubbleDensity - "boiling curve specific density of water" - extends Modelica.Icons.Function; - algorithm - dl := getProp_REFPROP_check("d", "pq", sat.psat,0,reference_X,1); - end bubbleDensity; - - -redeclare replaceable partial function extends molarMass - "Return the molar mass of the medium" - extends Modelica.Icons.Function; -algorithm - MM:=state.MM; -end molarMass; - - -redeclare replaceable partial function extends setState_phX - "Calculates medium properties from p,h,X" - // input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX("+String(p)+","+String(h)+",X)..."); - end if; - state := setState("ph",p,h,X,phase) ",fluidnames)"; -end setState_phX; - - - redeclare function density_phX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X - "composition defined by mass fractions"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_phX("+String(p)+","+String(h)+",X)"); - end if; - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - d :=getProp_REFPROP_check("d", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pdX(p,d,X,phase), - p=pressure_hdX(h,d,X,phase))); - end density_phX; - - - redeclare function temperature_phX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_phX("+String(p)+","+String(h)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - p=pressure_ThX(T,h,X,phase))); - end temperature_phX; - - -redeclare replaceable partial function extends setState_pTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pTX("+String(p)+","+String(T)+",X)..."); - end if; - state := setState("pT",p,T,X,phase) ",fluidnames)"; -end setState_pTX; - - - redeclare function density_pTX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - // input String fluidnames; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_pTX("+String(p)+","+String(T)+",X)..."); - end if; - d :=getProp_REFPROP_check("d", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_pdX(p,d,X,phase), - p=pressure_dTX(d,T,X,phase))); - end density_pTX; - - - redeclare function specificEnthalpy_pTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pTX("+String(p)+","+String(T)+",X)..."); - end if; - // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); - h :=getProp_REFPROP_check("h", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase), - p=pressure_ThX(T,h,X,phase))); - end specificEnthalpy_pTX; - - - redeclare function specificEntropy_pTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pTX("+String(p)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pT",p,T,X,phase); - annotation(LateInline=true,inverse(T=temperature_psX(p,s,X,phase), - p=pressure_TsX(T,s,X,phase))); - end specificEntropy_pTX; - - -redeclare replaceable partial function extends setState_psX - "Calculates medium properties from p,s,X" -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_psX("+String(p)+","+String(s)+",X)..."); - end if; - state := setState("ps",p,s,X,phase) ",fluidnames)"; -end setState_psX; - - - redeclare function temperature_psX - "calls REFPROP-Wrapper, returns temperature" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(s)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pTX(p,T,X,phase), - p=pressure_TsX(T,s,X,phase))); - end temperature_psX; - - - redeclare function specificEnthalpy_psX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - // input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; - /*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_psX("+String(p)+","+String(s)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - p=pressure_hsX(h,s,X,phase))); - end specificEnthalpy_psX; - - - redeclare function density_psX "calls REFPROP-Wrapper, returns density" - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 - "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Density d; - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running density_psX("+String(p)+","+String(s)+",X)"); - end if; - d :=getProp_REFPROP_check("d", "ps",p,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - p=pressure_dsX(d,s,X,phase))); - end density_psX; - - -redeclare replaceable partial function extends setState_dTX -// input String fluidnames; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX("+String(d)+","+String(T)+",X)..."); - end if; - state := setState("dT",d,T,X,phase) ",fluidnames)"; -end setState_dTX; - - -redeclare function extends dynamicViscosity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running dynamicViscosity"); - end if; - eta := getProp_REFPROP_check("v", "Td",state.T,state.d,state.X,state.phase); -end dynamicViscosity; - - -redeclare function extends thermalConductivity -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running thermalConductivity"); - end if; - lambda := getProp_REFPROP_check("l", "Td",state.T,state.d,state.X,state.phase); -end thermalConductivity; - - - redeclare function extends specificHeatCapacityCp - - algorithm - cp:=state.cp; - end specificHeatCapacityCp; - - - redeclare function extends specificHeatCapacityCv - - algorithm - cv:=state.cv; - end specificHeatCapacityCv; - - -redeclare function pressure "Return pressure from state record" - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.Pressure p "Vapour quality"; -algorithm - p := state.p; -end pressure; - - -redeclare function specificEnthalpy - "Return specific enthalpy from state record" - input ThermodynamicState state "Thermodynamic state record"; - output Modelica.SIunits.SpecificEnthalpy h "Vapour quality"; -algorithm - h := state.h; -end specificEnthalpy; - - -redeclare function vapourQuality "Return vapour quality" - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; -algorithm - x := state.x; -end vapourQuality; - - - annotation (Documentation(info=" -

-REFPROPMediumPureSubstance is a package that delivers REFPROP data to a model based on and compatible to the Modelica.Media library. -It can be used to calculate two-phase states of all fluids whose data is delivered with REFPROP. It has been developed and tested only in Dymola up to 2012 FD01. -

-

-All files in this library, including the C source files are released under the Modelica License 2. -

-

Installation

-The installation basically consists in copying 2 files and changing one line in this package: -
    -
  • We need access to the REFPROP.DLL and to the Fluid-Data directory in the REFPROP directory. - So you need to set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of this parent package). - Make sure you mask the backslashes. It should look something like -
    constant String REFPROP_PATH = \"C:\\\\Program Files\\\\REFPROP\\\\\";
  • -
  • We need REFPROP_WRAPPER.LIB in %DYMOLADIR%\\BIN\\LIB\ and REFPROP_WRAPPER.H in %DYMOLADIR%\\SOURCE\\ (%DYMOLADIR% is DYMOLA's program directory)
  • -
-This package needs the package PartialMixtureMediumTwoPhase which should be included in the parent package. - -

-

Usage

-Being based on Modelica.Media, it is used like the two-phase water model:
-Create an Instance of REFPROPMediumPureSubstance and pass the components.defines the medium components (medium names are the names of the .fld files in the %REFPROP%\\fluids directory): -
-  package Medium = REFPROPMediumPureSubstance (final substanceNames={\"nitrogen\"});
-
-Create an Instance of REFPROPMediumPureSubstance.Baseproperties: -
-  Medium.BaseProperties props;
-
-You can then use the Baseproperties model to define the thermodynamic state and calculate the corresponding properties. -
-  props.p = 1e5;
-  props.T = 300;
-  d = props.d;
-  h = props.h;
-
-

Any combination of the pressure, temperature, specific enthalpy, specific entropy and density (p,T,h,s,d) can be used to define a -thermodynamic state. Explicit functions for all combinations exist in REFPROP and likewise in the REFPROPMedium package. -The calculation of all variables of a thermodynamic state, however, is by default done by setState_phX, so p and h have to be -calculated from the given combination of two variables first. Actually, by doing this, REFPROP already calculates all variables -of the thermodynamic state, but they cannot be used directly. This is a limitation of DYMOLA, as it is not able to invert a function -returning an array. -You can change the set of variables the property model is explicit for by setting the string variable explicitVars e.g. to \"pT\" or \"dT\": -

-package Medium = REFPROPMedium(final substanceNames={\"water\"}, final explicitVars = \"pT\");
-
-

-

All calculated values are returned in SI-Units and are mass based. -

- - -

Details

- All property functions contain a definition of their inverses. So, in many cases no numerical inversion by the solver is needed because - explicit REFPROP functions are used (meaning, numerical inversion happens in REFPROP instead).
- Example: When explicitVars are set to \"ph\" and p and T are given, the specificEnthalpy is calculated first using the inverse function of - Temperature_phX --> specificEnthalpy_pTX. With p and h known all other variables are calculated by setstate_phX. -

- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -")); -end REFPROPMediumPureSubstance; diff --git a/REFPROPMediumPureSubstance/package.order b/REFPROPMediumPureSubstance/package.order deleted file mode 100644 index 4a5597f..0000000 --- a/REFPROPMediumPureSubstance/package.order +++ /dev/null @@ -1,78 +0,0 @@ -SaturationProperties -saturationPressure -saturationTemperature -debugmode -explicitVars -fluidnames -rpConstants -ThermodynamicState -BaseProperties -StrJoin -partialREFPROP -getSatProp_REFPROP_check -getSatProp_REFPROP -getProp_REFPROP_check -getProp_REFPROP -setState -specificEntropy -density -dewEnthalpy -dewEntropy -dewDensity -bubbleEnthalpy -bubbleEntropy -bubbleDensity -molarMass -setState_phX -density_phX -temperature_phX -specificEntropy_phX -setState_pTX -density_pTX -specificEnthalpy_pTX -specificEntropy_pTX -setState_psX -temperature_psX -specificEnthalpy_psX -density_psX -setState_pdX -temperature_pdX -specificEnthalpy_pdX -specificEntropy_pdX -setState_ThX -pressure_ThX -density_ThX -specificEntropy_ThX -setState_dTX -pressure_dTX -specificEnthalpy_dTX -specificEntropy_dTX -setState_TsX -pressure_TsX -specificEnthalpy_TsX -density_TsX -setState_hdX -pressure_hdX -temperature_hdX -specificEntropy_hdX -setState_hsX -pressure_hsX -temperature_hsX -density_hsX -setState_dsX -pressure_dsX -temperature_dsX -specificEnthalpy_dsX -setState_pqX -density_pqX -pressure_TqX -specificEnthalpy_pqX -specificEntropy_pqX -temperature_pqX -dynamicViscosity -thermalConductivity -specificHeatCapacityCp -specificHeatCapacityCv -pressure -specificEnthalpy -vapourQuality diff --git a/REFPROPMediumPureSubstance/partialREFPROP.mo b/REFPROPMediumPureSubstance/partialREFPROP.mo deleted file mode 100644 index 1211a40..0000000 --- a/REFPROPMediumPureSubstance/partialREFPROP.mo +++ /dev/null @@ -1,9 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -partial function partialREFPROP "Declaration of array props" -//used by getSatProp_REFPROP_check() and getProp_REFPROP_check() - extends Modelica.Icons.Function; -protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; -end partialREFPROP; diff --git a/REFPROPMediumPureSubstance/pressure_ThX.mo b/REFPROPMediumPureSubstance/pressure_ThX.mo deleted file mode 100644 index d976431..0000000 --- a/REFPROPMediumPureSubstance/pressure_ThX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_ThX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_ThX("+String(T)+","+String(h)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_pTX(p,T,X,phase), - T=temperature_phX(p,h,X,phase))); -end pressure_ThX; diff --git a/REFPROPMediumPureSubstance/pressure_TqX.mo b/REFPROPMediumPureSubstance/pressure_TqX.mo deleted file mode 100644 index 1dbbf7c..0000000 --- a/REFPROPMediumPureSubstance/pressure_TqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_TqX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; - //T=quality_pTX(p,T,X,phase) -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TqX("+String(T)+","+String(q)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "Tq",T,q,X,phase); - annotation(LateInline=true,inverse(T=temperature_pqX(p,q,X,phase))); -end pressure_TqX; diff --git a/REFPROPMediumPureSubstance/pressure_TsX.mo b/REFPROPMediumPureSubstance/pressure_TsX.mo deleted file mode 100644 index ce0e7ef..0000000 --- a/REFPROPMediumPureSubstance/pressure_TsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_TsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_TsX("+String(T)+","+String(s)+",X)..."); - end if; - p :=getProp_REFPROP_check("p", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_pTX(p,T,X,phase), - T=temperature_psX(p,s,X,phase))); -end pressure_TsX; diff --git a/REFPROPMediumPureSubstance/pressure_dTX.mo b/REFPROPMediumPureSubstance/pressure_dTX.mo deleted file mode 100644 index b5c5b99..0000000 --- a/REFPROPMediumPureSubstance/pressure_dTX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_dTX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dTX("+String(d)+","+String(T)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_pTX(p,T,X,phase), - T=temperature_pdX(p,d,X,phase))); -end pressure_dTX; diff --git a/REFPROPMediumPureSubstance/pressure_dsX.mo b/REFPROPMediumPureSubstance/pressure_dsX.mo deleted file mode 100644 index 22e45c9..0000000 --- a/REFPROPMediumPureSubstance/pressure_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_dsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_dsX("+String(d)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_pdX(p,d,X,phase), - d=density_psX(p,s,X,phase))); -end pressure_dsX; diff --git a/REFPROPMediumPureSubstance/pressure_hdX.mo b/REFPROPMediumPureSubstance/pressure_hdX.mo deleted file mode 100644 index 3d3cb16..0000000 --- a/REFPROPMediumPureSubstance/pressure_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_hdX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hdX("+String(h)+","+String(d)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_phX(p,h,X,phase), - h=specificEnthalpy_pdX(p,d,X,phase))); -end pressure_hdX; diff --git a/REFPROPMediumPureSubstance/pressure_hsX.mo b/REFPROPMediumPureSubstance/pressure_hsX.mo deleted file mode 100644 index 2df7c7d..0000000 --- a/REFPROPMediumPureSubstance/pressure_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function pressure_hsX "calls REFPROP-Wrapper, returns pressure" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Pressure p; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running pressure_hsX("+String(h)+","+String(s)+",X)"); - end if; - p :=getProp_REFPROP_check("p", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_phX(p,h,X,phase), - h=specificEnthalpy_psX(p,s,X,phase))); -end pressure_hsX; diff --git a/REFPROPMediumPureSubstance/setState.mo b/REFPROPMediumPureSubstance/setState.mo deleted file mode 100644 index a28d557..0000000 --- a/REFPROPMediumPureSubstance/setState.mo +++ /dev/null @@ -1,45 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState "Calculates medium properties" - extends partialREFPROP; - input String statevars; - input Real statevar1; - input Real statevar2; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -// Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); -/*protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function";*/ - -algorithm - assert(size(X,1)>0,"The mass fraction vector must have at least 1 element."); - getProp_REFPROP("",statevars,fluidnames,props,statevar1,statevar2,X,phase,errormsg); - assert(props[1]==0,"Error in REFPROP wrapper function: "+errormsg +"\n"); -/* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; - - If q = 998 Then Quality = Trim2("Superheated vapor with T>Tc") - If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") - If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ - state := ThermodynamicState( p= props[2], - T= props[3], - MM= props[4], - d=props[5], - d_l=props[6], - d_g=props[7], - x=min(max(props[8],0),1), - u=props[9], - h=props[10], - s=props[11], - cv=props[12], - cp=props[13], - c=props[14], - phase=if props[8]>0 and props[8]<1 then 2 else 1); -/* - X= X, - X_l=props[17:16+nX], - X_g=props[17+nX:16+2*nX], -*/ -end setState; diff --git a/REFPROPMediumPureSubstance/setState_ThX.mo b/REFPROPMediumPureSubstance/setState_ThX.mo deleted file mode 100644 index d166644..0000000 --- a/REFPROPMediumPureSubstance/setState_ThX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_ThX "Calculates medium properties from T,h,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEnthalpy h "Enthalpy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_ThX("+String(T)+","+String(h)+",X)..."); - end if; - state := setState("Th",T,h,X,phase) ",fluidnames)"; -end setState_ThX; diff --git a/REFPROPMediumPureSubstance/setState_TsX.mo b/REFPROPMediumPureSubstance/setState_TsX.mo deleted file mode 100644 index a4da8af..0000000 --- a/REFPROPMediumPureSubstance/setState_TsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_TsX "Calculates medium properties from T,s,X" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_TsX("+String(T)+","+String(s)+",X)..."); - end if; - state := setState("Ts",T,s,X,phase) ",fluidnames)"; -end setState_TsX; diff --git a/REFPROPMediumPureSubstance/setState_dsX.mo b/REFPROPMediumPureSubstance/setState_dsX.mo deleted file mode 100644 index 057f7ed..0000000 --- a/REFPROPMediumPureSubstance/setState_dsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_dsX "Calculates medium properties from d,s,X" - extends Modelica.Icons.Function; - input Density d "Temperature"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dsX("+String(d)+","+String(s)+",X)..."); - end if; - state := setState("ds",d,s,X,phase) ",fluidnames)"; -end setState_dsX; diff --git a/REFPROPMediumPureSubstance/setState_hdX.mo b/REFPROPMediumPureSubstance/setState_hdX.mo deleted file mode 100644 index dbb2425..0000000 --- a/REFPROPMediumPureSubstance/setState_hdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_hdX "Calculates medium properties from h,d,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input Density d "Temperature"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_hdX("+String(h)+","+String(d)+",X)..."); - end if; - state := setState("hd",h,d,X,phase) ",fluidnames)"; -end setState_hdX; diff --git a/REFPROPMediumPureSubstance/setState_hsX.mo b/REFPROPMediumPureSubstance/setState_hsX.mo deleted file mode 100644 index 23ea017..0000000 --- a/REFPROPMediumPureSubstance/setState_hsX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_hsX "Calculates medium properties from h,s,X" - extends Modelica.Icons.Function; - input SpecificEnthalpy h "Enthalpy"; - input SpecificEntropy s "Entropy"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running ("+String(h)+","+String(s)+",X)..."); - end if; - state := setState("hs",h,s,X,phase) ",fluidnames)"; -end setState_hsX; diff --git a/REFPROPMediumPureSubstance/setState_pdX.mo b/REFPROPMediumPureSubstance/setState_pdX.mo deleted file mode 100644 index ce95e6a..0000000 --- a/REFPROPMediumPureSubstance/setState_pdX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_pdX "Calculates medium properties from p,d,X" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Density d "Density"; - input MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pdX("+String(p)+","+String(d)+",X)..."); - end if; - state := setState("pd",p,d,X,phase) ",fluidnames)"; -end setState_pdX; diff --git a/REFPROPMediumPureSubstance/setState_pqX.mo b/REFPROPMediumPureSubstance/setState_pqX.mo deleted file mode 100644 index 10556ac..0000000 --- a/REFPROPMediumPureSubstance/setState_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function setState_pqX "Calculates medium properties from p,q,X" - extends Modelica.Icons.Function; - input Modelica.SIunits.AbsolutePressure p "Pressure"; - input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; - input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; -// input String fluidnames; - output ThermodynamicState state "thermodynamic state record"; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_pqX("+String(p)+","+String(q)+",X)..."); - end if; - state := setState("pq",p,q,X,phase) ",fluidnames)"; -end setState_pqX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo deleted file mode 100644 index 786c847..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_TsX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_TsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX("+String(T)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "Ts",T,s,X,phase); - annotation(LateInline=true,inverse(s = specificEntropy_ThX(T,h,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEnthalpy_TsX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo deleted file mode 100644 index de59101..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_dTX.mo +++ /dev/null @@ -1,19 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_dTX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dTX("+String(d)+","+String(T)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - T=temperature_hdX(h,d,X,phase))); -end specificEnthalpy_dTX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo deleted file mode 100644 index 80c85d5..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_dsX.mo +++ /dev/null @@ -1,22 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_dsX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_dsX("+String(d)+","+String(s)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_hdX(h,d,X,phase), - d=density_hsX(h,s,X,phase))); -end specificEnthalpy_dsX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo deleted file mode 100644 index 5c9c9ef..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_pdX.mo +++ /dev/null @@ -1,18 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_pdX - "calls REFPROP-Wrapper, returns specific enthalpy" - //does not extend existing function from PartialMedium because there the algorithm is already defined - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pdX("+String(p)+","+String(d)+",X)..."); - end if; - h :=getProp_REFPROP_check("h", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_phX(p,h,X,phase), - p=pressure_hdX(h,d,X,phase))); -end specificEnthalpy_pdX; diff --git a/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo b/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo deleted file mode 100644 index 858f068..0000000 --- a/REFPROPMediumPureSubstance/specificEnthalpy_pqX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEnthalpy_pqX - "calls REFPROP-Wrapper, returns specific enthalpy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEnthalpy h; -// annotation(LateInline=true,inverse(p = pressure_hqX(h,q,X,phase),quality_phX(p,h,X,phase))); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEnthalpy_pqX("+String(p)+","+String(q)+",X)"); - end if; - h :=getProp_REFPROP_check("h", "pq",p,q,X,phase); -end specificEnthalpy_pqX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_ThX.mo b/REFPROPMediumPureSubstance/specificEntropy_ThX.mo deleted file mode 100644 index eff9438..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_ThX.mo +++ /dev/null @@ -1,20 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_ThX - extends Modelica.Icons.Function; - input Modelica.SIunits.Temperature T; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_ThX("+String(T)+","+String(h)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "Th",T,h,X,phase); - annotation(LateInline=true,inverse(h = specificEnthalpy_TsX(T,s,X,phase), - T=temperature_hsX(h,s,X,phase))); -end specificEntropy_ThX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_dTX.mo b/REFPROPMediumPureSubstance/specificEntropy_dTX.mo deleted file mode 100644 index b676dc0..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_dTX.mo +++ /dev/null @@ -1,17 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_dTX - extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.Temperature T; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_dTX("+String(d)+","+String(T)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "dT",d,T,X,phase); - annotation(LateInline=true,inverse(d = density_TsX(T,s,X,phase), - T=temperature_dsX(d,s,X,phase))); -end specificEntropy_dTX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_hdX.mo b/REFPROPMediumPureSubstance/specificEntropy_hdX.mo deleted file mode 100644 index 4bc5bbe..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_hdX - extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_hdX("+String(h)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_hsX(h,s,X,phase), - h=specificEnthalpy_dsX(d,s,X,phase))); -end specificEntropy_hdX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_pdX.mo b/REFPROPMediumPureSubstance/specificEntropy_pdX.mo deleted file mode 100644 index edf6224..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_pdX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pdX("+String(p)+","+String(d)+",X)"); - end if; - s:=getProp_REFPROP_check("s", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d = density_psX(p,s,X,phase), - p=pressure_dsX(d,s,X,phase))); -end specificEntropy_pdX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_phX.mo b/REFPROPMediumPureSubstance/specificEntropy_phX.mo deleted file mode 100644 index 7fb508f..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_phX.mo +++ /dev/null @@ -1,21 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_phX - extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; -// input String fluidnames; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -/*protected - Real[14+2*nX] props; - String errormsg=StrJoin(fill("xxxx",10),"");*/ -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_phX("+String(p)+","+String(h)+",X)..."); - // p="+String(p)+",h="+String(h)+", X={"+String(X[1])+","+String(X[2])+"}"); - end if; - s:=getProp_REFPROP_check("s", "ph",p,h,X,phase); - annotation(LateInline=true,inverse(h=specificEnthalpy_psX(p,s,X,phase), - p=pressure_hsX(h,s,X,phase))); -end specificEntropy_phX; diff --git a/REFPROPMediumPureSubstance/specificEntropy_pqX.mo b/REFPROPMediumPureSubstance/specificEntropy_pqX.mo deleted file mode 100644 index e8c5bf2..0000000 --- a/REFPROPMediumPureSubstance/specificEntropy_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function specificEntropy_pqX "calls REFPROP-Wrapper, returns specific entropy" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Real q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.SpecificEntropy s; -// annotation(LateInline=true,inverse(p = pressure_sqX(s,q,X,phase),q=quality_psX(p,s,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running specificEntropy_pqX("+String(p)+","+String(q)+",X)"); - end if; - s :=getProp_REFPROP_check("s", "pq",p,q,X,phase); -end specificEntropy_pqX; diff --git a/REFPROPMediumPureSubstance/temperature_dsX.mo b/REFPROPMediumPureSubstance/temperature_dsX.mo deleted file mode 100644 index d3e7893..0000000 --- a/REFPROPMediumPureSubstance/temperature_dsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_dsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Density d; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_dsX("+String(d)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "ds",d,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_dTX(d,T,X,phase), - d=density_TsX(T,s,X,phase))); -end temperature_dsX; diff --git a/REFPROPMediumPureSubstance/temperature_hdX.mo b/REFPROPMediumPureSubstance/temperature_hdX.mo deleted file mode 100644 index e58dfc9..0000000 --- a/REFPROPMediumPureSubstance/temperature_hdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_hdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hdX("+String(h)+","+String(d)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hd",h,d,X,phase); - annotation(LateInline=true,inverse(d=density_ThX(T,h,X,phase), - h=specificEnthalpy_dTX(d,T,X,phase))); -end temperature_hdX; diff --git a/REFPROPMediumPureSubstance/temperature_hsX.mo b/REFPROPMediumPureSubstance/temperature_hsX.mo deleted file mode 100644 index 9c447e9..0000000 --- a/REFPROPMediumPureSubstance/temperature_hsX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_hsX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.SpecificEnthalpy h; - input Modelica.SIunits.SpecificEntropy s; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_hsX("+String(h)+","+String(s)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "hs",h,s,X,phase); - annotation(LateInline=true,inverse(s=specificEntropy_ThX(T,h,X,phase), - h=specificEnthalpy_TsX(T,s,X,phase))); -end temperature_hsX; diff --git a/REFPROPMediumPureSubstance/temperature_pdX.mo b/REFPROPMediumPureSubstance/temperature_pdX.mo deleted file mode 100644 index 11d5b91..0000000 --- a/REFPROPMediumPureSubstance/temperature_pdX.mo +++ /dev/null @@ -1,16 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_pdX "calls REFPROP-Wrapper, returns temperature" -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Density d; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_psX("+String(p)+","+String(d)+",X)..."); - end if; - T :=getProp_REFPROP_check("T", "pd",p,d,X,phase); - annotation(LateInline=true,inverse(d=density_pTX(p,T,X,phase), - p=pressure_dTX(d,T,X,phase))); -end temperature_pdX; diff --git a/REFPROPMediumPureSubstance/temperature_pqX.mo b/REFPROPMediumPureSubstance/temperature_pqX.mo deleted file mode 100644 index 8f5549a..0000000 --- a/REFPROPMediumPureSubstance/temperature_pqX.mo +++ /dev/null @@ -1,15 +0,0 @@ -within MediaTwoPhaseMixture.REFPROPMediumPureSubstance; -function temperature_pqX -extends Modelica.Icons.Function; - input Modelica.SIunits.Pressure p; - input MassFraction q; - input MassFraction X[:]=reference_X "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temperature T; -// annotation(LateInline=true,inverse(p = pressure_TqX(T,q,X,phase),q=quality_pTX(p,T,X,phase)); -algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running temperature_pqX("+String(p)+","+String(q)+",X)"); - end if; - T :=getProp_REFPROP_check("T", "pq",p,q,X,phase); -end temperature_pqX; diff --git a/Testers/PentaneTester.mo b/Testers/PentaneTester.mo new file mode 100644 index 0000000..40aa369 --- /dev/null +++ b/Testers/PentaneTester.mo @@ -0,0 +1,52 @@ +within REFPROP2Modelica.Testers; +model PentaneTester "Evaporation of pentane at 1 bar" +package Medium = REFPROP2Modelica.Media.Pentane ( debugmode=true); +// ",final explicitVars = "pd""; +//package Medium = REFPROP2Modelica.REFPROPMedium(final substanceNames={"CO2","water"}); + Medium.BaseProperties props; +// Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); + Modelica.SIunits.Density d; + Modelica.SIunits.SpecificEntropy s; + Modelica.SIunits.Temperature Tsat; + Modelica.SIunits.Pressure psat; + */ +//Modelica.SIunits.Pressure p=Medium.pressure(props.state); +// Modelica.SIunits.MolarMass MM; +/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); + +Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); +Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); +*/ +// Real q = Medium.vapourQuality(props.state); +// Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); +// Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); +equation + props.p = 1e5; + props.h = -1e5+time*6e5; + + // props.s = 5.88105; +// props.T = 400; +// props.state.x = 0.5; +// props.Xi = {.5}; +// props.X = {.1,.9}; +// props.Xi = {.5}; + // d = props.d; + //h = props.h; + //h = Medium.dewEnthalpy(props.sat); + //d = Medium.density(props.state); + //s = specificEntropy(props.state); + //s = props.state.s; +// MM = Medium.molarMass(props.state); +/* + Tsat = Medium.saturationTemperature(props.p,props.X); +// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); + psat = Medium.saturationPressure(props.T,props.X); +// psat = Medium.pressure_TqX(props.T,0.5,props.X); +// h = Medium.dewEnthalpy(props.sat); +// s = Medium.dewEntropy(props.sat); + s = Medium.bubbleEntropy(props.sat); +// d = Medium.dewDensity(props.sat); + d = Medium.bubbleDensity(props.sat); +*/ +end PentaneTester; diff --git a/Examples/PropsMixture.mo b/Testers/PropsMixture.mo similarity index 84% rename from Examples/PropsMixture.mo rename to Testers/PropsMixture.mo index 8345f7f..a97b8c6 100644 --- a/Examples/PropsMixture.mo +++ b/Testers/PropsMixture.mo @@ -1,61 +1,54 @@ -within MediaTwoPhaseMixture.Examples; -model PropsMixture -//package Medium = REFPROPMedium(final substanceNames={"isobutan"}); -//package Medium = REFPROPMedium(final substanceNames={"R12"}); -package Medium = REFPROPMedium(final substanceNames={"isobutan","propane"}); -// ",final explicitVars = "pd""; -//package Medium = MediaTwoPhaseMixture.REFPROPMedium(final substanceNames={"CO2","water"}); - - Medium.BaseProperties props; - - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); - -/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); - Modelica.SIunits.Density d; - Modelica.SIunits.SpecificEntropy s; - Modelica.SIunits.Temperature Tsat; - Modelica.SIunits.Pressure psat; - */ -Modelica.SIunits.Pressure p=Medium.pressure(props.state); -// Modelica.SIunits.MolarMass MM; -/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); - -Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); -Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); -*/ - Real q = Medium.vapourQuality(props.state); - Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); -equation - - props.p = 1e5; - props.h = 0+time*8e5; - // props.s = 5.88105; -// props.T = 400; -// props.state.x = 0.5; -// props.Xi = {.5}; -// props.X = {.1,.9}; - props.Xi = {.5}; - - // d = props.d; - //h = props.h; - //h = Medium.dewEnthalpy(props.sat); - - //d = Medium.density(props.state); - //s = specificEntropy(props.state); - //s = props.state.s; -// MM = Medium.molarMass(props.state); - -/* - Tsat = Medium.saturationTemperature(props.p,props.X); -// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); - psat = Medium.saturationPressure(props.T,props.X); -// psat = Medium.pressure_TqX(props.T,0.5,props.X); -// h = Medium.dewEnthalpy(props.sat); -// s = Medium.dewEntropy(props.sat); - s = Medium.bubbleEntropy(props.sat); -// d = Medium.dewDensity(props.sat); - d = Medium.bubbleDensity(props.sat); -*/ - -end PropsMixture; +within REFPROP2Modelica.Testers; +model PropsMixture +//package Medium = REFPROPMedium(final substanceNames={"isobutan"}); +//package Medium = REFPROPMedium(final substanceNames={"R12"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( + final substanceNames={"isobutan","propane"}); +// ",final explicitVars = "pd""; +//package Medium = REFPROP2Modelica.REFPROPMedium(final substanceNames={"CO2","water"}); + Medium.BaseProperties props; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); + Modelica.SIunits.Density d; + Modelica.SIunits.SpecificEntropy s; + Modelica.SIunits.Temperature Tsat; + Modelica.SIunits.Pressure psat; + */ +Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); +// Modelica.SIunits.MolarMass MM; +/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); + +Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); +Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); +*/ + Real q = Medium.vapourQuality(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); +equation + props.p = 1e5; + props.h = 0+time*8e5; + // props.s = 5.88105; +// props.T = 400; +// props.state.x = 0.5; +// props.Xi = {.5}; +// props.X = {.1,.9}; + props.Xi = {.5}; + // d = props.d; + //h = props.h; + //h = Medium.dewEnthalpy(props.sat); + //d = Medium.density(props.state); + //s = specificEntropy(props.state); + //s = props.state.s; +// MM = Medium.molarMass(props.state); +/* + Tsat = Medium.saturationTemperature(props.p,props.X); +// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); + psat = Medium.saturationPressure(props.T,props.X); +// psat = Medium.pressure_TqX(props.T,0.5,props.X); +// h = Medium.dewEnthalpy(props.sat); +// s = Medium.dewEntropy(props.sat); + s = Medium.bubbleEntropy(props.sat); +// d = Medium.dewDensity(props.sat); + d = Medium.bubbleDensity(props.sat); +*/ +end PropsMixture; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo new file mode 100644 index 0000000..2bc5347 --- /dev/null +++ b/Testers/PropsMixtureTwo.mo @@ -0,0 +1,15 @@ +within REFPROP2Modelica.Testers; +model PropsMixtureTwo +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( + final substanceNames={"isobutan","propane"}); + Medium.BaseProperties props; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); + Real q = Medium.vapourQuality(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); +equation + props.p = 1e5; + props.h = 0+time*8e5; + props.Xi = {.5}; +end PropsMixtureTwo; diff --git a/Examples/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo similarity index 89% rename from Examples/PropsPureSubstance.mo rename to Testers/PropsPureSubstance.mo index 1637ec0..94d9161 100644 --- a/Examples/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -1,55 +1,49 @@ -within MediaTwoPhaseMixture.Examples; -model PropsPureSubstance -//package Medium = Modelica.Media.Water.WaterIF97_ph; -//package Medium = MediaTwoPhaseMixture.Water_MixtureTwoPhase_pT; -//package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); -//package Medium = REFPROPMedium(final substanceNames={"ammonia"}); -//package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = MediaTwoPhaseMixture.REFPROPMediumPureSubstance (final substanceNames={"butane"}); - -//package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); -//package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); - - Medium.BaseProperties props; -// Modelica.SIunits.Density d=Medium.density_phX(props.p,props.h); -// d = Medium.bubbleDensity(props.sat); -// d = Medium.density_pTX(1e5,300); -// Modelica.SIunits.SpecificEnthalpy h; -// Modelica.SIunits.SpecificEntropy s; -// Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); -// Modelica.SIunits.MolarMass MM; - Real q= Medium.vapourQuality(props.state); -// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; -// Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); -// Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); - Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); -equation - props.p = 1e5 "sine_p.y"; - props.h = 0+time*722774; - -// props.s = 5.88105; -// props.T = 350; -// props.Xi = fill(0,0); - - //d = props.d; - //h = props.h; - //h = Medium.dewEnthalpy(props.sat); - - //d = Medium.density(props.state); - //s = specificEntropy(props.state); - //s = props.state.s; -// MM = Medium.molarMass(props.state); -// Tsat = Medium.saturationTemperature(props.p,props.X); -// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); -// psat = Medium.saturationPressure(props.T,props.X); -// psat = Medium.pressure_TqX(props.T,0.5,props.X); -// h = Medium.dewEnthalpy(props.sat); -// s = Medium.dewEntropy(props.sat); -// s = Medium.bubbleEntropy(props.sat); -// d = Medium.dewDensity(props.sat); - - annotation (experiment(StopTime=10, NumberOfIntervals=1000), - __Dymola_experimentSetupOutput); -end PropsPureSubstance; +within REFPROP2Modelica.Testers; +model PropsPureSubstance +//package Medium = Modelica.Media.Water.WaterIF97_ph; +//package Medium = REFPROP2Modelica.Water_MixtureTwoPhase_pT; +//package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); +//package Medium = REFPROPMedium(final substanceNames={"ammonia"}); +//package Medium = REFPROPMedium(final substanceNames={"co2"}); +package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); +//package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); +//package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); + Medium.BaseProperties props; +// Modelica.SIunits.Density d=Medium.density_phX(props.p,props.h); +// d = Medium.bubbleDensity(props.sat); +// d = Medium.density_pTX(1e5,300); +// Modelica.SIunits.SpecificEnthalpy h; +// Modelica.SIunits.SpecificEntropy s; +// Modelica.SIunits.Temperature T=props.T; + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); +// Modelica.SIunits.MolarMass MM; + Real q= Medium.vapourQuality(props.state); +// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; +// Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); +// Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); + Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); +equation + props.p = 1e5 "sine_p.y"; + props.h = 0+time*722774; +// props.s = 5.88105; +// props.T = 350; +// props.Xi = fill(0,0); + //d = props.d; + //h = props.h; + //h = Medium.dewEnthalpy(props.sat); + //d = Medium.density(props.state); + //s = specificEntropy(props.state); + //s = props.state.s; +// MM = Medium.molarMass(props.state); +// Tsat = Medium.saturationTemperature(props.p,props.X); +// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); +// psat = Medium.saturationPressure(props.T,props.X); +// psat = Medium.pressure_TqX(props.T,0.5,props.X); +// h = Medium.dewEnthalpy(props.sat); +// s = Medium.dewEntropy(props.sat); +// s = Medium.bubbleEntropy(props.sat); +// d = Medium.dewDensity(props.sat); + annotation (experiment(StopTime=10, NumberOfIntervals=1000), + __Dymola_experimentSetupOutput); +end PropsPureSubstance; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo new file mode 100644 index 0000000..d85be9d --- /dev/null +++ b/Testers/R410mixTester.mo @@ -0,0 +1,15 @@ +within REFPROP2Modelica.Testers; +model R410mixTester "Density of saturated R410 vapour" +package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); + Medium.BaseProperties props; + Medium.Density d; + Medium.SpecificEnthalpy h(start=300e3); + Medium.AbsolutePressure p = Medium.pressure(props.state); + Medium.SpecificHeatCapacity cv = Medium.specificHeatCapacityCv(props.state); +equation + props.p = 101325; + h = Medium.dewEnthalpy(props.sat); + props.h = h; + props.d = d; + props.Xi = {0.697615}; +end R410mixTester; diff --git a/Water_MixtureTwoPhase_pT/package.mo b/Testers/Water_MixtureTwoPhase_pT.mo similarity index 88% rename from Water_MixtureTwoPhase_pT/package.mo rename to Testers/Water_MixtureTwoPhase_pT.mo index 5aa7ebd..3d8560f 100644 --- a/Water_MixtureTwoPhase_pT/package.mo +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -1,319 +1,286 @@ -within MediaTwoPhaseMixture; -package Water_MixtureTwoPhase_pT "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - - - extends PartialMixtureTwoPhaseMedium( - final mediumName="TwoPhaseMixtureWater", - final substanceNames={"water"}, - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = BrineConstants); -// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - - redeclare model extends BaseProperties "Base properties of medium" - - Real GVF=q*d/d_g "gas void fraction"; - Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ - Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); - Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); - Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) - "(min=0,max=1) gas phase mass fraction"; - // Integer phase_out "calculated phase"; - //END no gas case - equation - u = h - p/d; - MM = M_H2O; - R = Modelica.Constants.R/MM; - - //End GVF - - //DENSITY - // q = vapourQuality(state); - d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); - // d = d_l/(1-q*(1-d_l/d_g)); - //End DENSITY - - //ENTHALPY - h = specificEnthalpy_pTX(p,T,X); - /* - if (p_H2O>p) then - h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); - else - h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); - end if; - h_gas_dissolved = 0; - Delta_h_solution = solutionEnthalpy(T) - "TODO: gilt nur bei gesättigter Lösung"; -*/ - //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); - //End ENTHALPY - - s=0 "TODO"; - - state = ThermodynamicState( - p=p, - T=T, - X=X, - X_l=X, - h=h, - GVF=GVF, - q=q, - s=0, - d_g=d_g, - d_l=d_l, - d=d, - phase=0) "phase_out"; - - sat.psat = p "TODO"; - sat.Tsat = T "saturationTemperature(p) TODO"; - sat.X = X; - - annotation (Documentation(info=""), - Documentation(revisions=" - -")); - end BaseProperties; - - - redeclare function specificEnthalpy_pTX - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - /* input MassFraction q "(min=0,max=1)"; - input Real y "molar fraction of gas in gas phase";*/ - // input Real[3] TP; - output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); - algorithm - // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); - annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); - end specificEnthalpy_pTX; - - - redeclare function temperature_phX - "numerically inverts specificEnthalpy_liquid_pTX" - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); - algorithm - // Modelica.Utilities.Streams.print("temperature_phX"); - - annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); - end temperature_phX; - - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T(unit="K") "Temperature of medium"; - MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Density d(start=300) "density"; - Real GVF "Gas Void Fraction"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real q "vapor quality on a mass basis [mass vapor/total mass]"; - - annotation (Documentation(info=" - -")); -end ThermodynamicState; - - - redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" - algorithm - hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); - end dewEnthalpy; - - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - algorithm - hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); - end bubbleEnthalpy; - - - redeclare function extends saturationTemperature - algorithm - //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); - T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); - end saturationTemperature; - - - redeclare function extends dynamicViscosity - algorithm - eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); - end dynamicViscosity; - - -redeclare function extends specificEntropy "specific entropy of water" -algorithm - s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); -end specificEntropy; - - -redeclare function specificEnthalpy_ps - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEnthalpy_ps; - - -redeclare function extends setState_psX - "Return thermodynamic state of water as function of p and s" -algorithm - state := ThermodynamicState( - d=density_ps(p,s), - T=temperature_ps(p,s), - phase=0, - h=specificEnthalpy_ps(p,s), - p=p, - X=X, - s=s, - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_psX; - - - redeclare function extends temperature "return temperature of ideal gas" - algorithm - T := state.T; - end temperature; - - - redeclare function extends density "return density of ideal gas" - algorithm - d := state.d; - end density; - - -redeclare function extends setState_pTX - "Return thermodynamic state of water as function of p and T" -algorithm - state := ThermodynamicState( - d=density_pT(p,T), - T=T, - phase=0, - h=specificEnthalpy_pTX(p,s), - p=p, - X=X, - s=specificEntropy_pT(p.T), - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_pTX; - - -redeclare function specificEntropy_pTX - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy T "Specific entropy"; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy s "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEntropy_pTX; - - - redeclare function extends thermalConductivity - "Thermal conductivity of water" - algorithm - lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( - state.d, - state.T, - state.p, - state.phase); - end thermalConductivity; - - - redeclare function extends specificHeatCapacityCp - "specific heat capacity at constant pressure of water" - - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); - else - cp := Modelica.Media.Water.IF97_Utilities.cp_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCp; - - - redeclare function extends saturationPressure - algorithm - p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); - end saturationPressure; - - - redeclare function extends specificHeatCapacityCv - "specific heat capacity at constant pressure of water" - - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); - else - cv := Modelica.Media.Water.IF97_Utilities.cv_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCv; - - annotation (Documentation(info=" -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT + "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMediumTwo( + final mediumName="TwoPhaseMixtureWater", + final substanceNames={"water"}, + final reducedX = true, + final singleState=false, + reference_X=cat(1,fill(0,nX-1),{1}), + fluidConstants = BrineConstants); +// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + redeclare model extends BaseProperties "Base properties of medium" + Real GVF=q*d/d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case + equation + u = h - p/d; + MM = M_H2O; + R = Modelica.Constants.R/MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p,T,X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei gesättigter Lösung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s=0 "TODO"; + state = ThermodynamicState( + p=p, + T=T, + X=X, + X_l=X, + h=h, + GVF=GVF, + q=q, + s=0, + d_g=d_g, + d_l=d_l, + d=d, + phase=0) "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation (Documentation(info=""), + Documentation(revisions=" + +")); + end BaseProperties; + + redeclare function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); + algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); + end specificEnthalpy_pTX; + + redeclare function temperature_phX + "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); + algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); + end temperature_phX; + +redeclare record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" +/* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start=300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start=300) "density liquid phase"; + Density d_g(start=300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation (Documentation(info=" + +")); +end ThermodynamicState; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" + algorithm + hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); + end dewEnthalpy; + + redeclare function extends bubbleEnthalpy + "boiling curve specific enthalpy of water" + algorithm + hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); + end bubbleEnthalpy; + + redeclare function extends saturationTemperature + algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); + end saturationTemperature; + + redeclare function extends dynamicViscosity + algorithm + eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); + end dynamicViscosity; + +redeclare function extends specificEntropy "specific entropy of water" +algorithm + s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + +redeclare function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + +redeclare function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state := ThermodynamicState( + d=density_ps(p,s), + T=temperature_ps(p,s), + phase=0, + h=specificEnthalpy_ps(p,s), + p=p, + X=X, + s=s, + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_psX; + + redeclare function extends temperature "return temperature of ideal gas" + algorithm + T := state.T; + end temperature; + + redeclare function extends density "return density of ideal gas" + algorithm + d := state.d; + end density; + +redeclare function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state := ThermodynamicState( + d=density_pT(p,T), + T=T, + phase=0, + h=specificEnthalpy_pTX(p,s), + p=p, + X=X, + s=specificEntropy_pT(p.T), + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_pTX; + +redeclare function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + + redeclare function extends thermalConductivity + "Thermal conductivity of water" + algorithm + lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( + state.d, + state.T, + state.p, + state.phase); + end thermalConductivity; + + redeclare function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp := Modelica.Media.Water.IF97_Utilities.cp_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCp; + + redeclare function extends saturationPressure + algorithm + p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); + end saturationPressure; + + redeclare function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv := Modelica.Media.Water.IF97_Utilities.cv_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCv; + + annotation (Documentation(info=" +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.mo b/Testers/package.mo new file mode 100644 index 0000000..67a63ea --- /dev/null +++ b/Testers/package.mo @@ -0,0 +1,3 @@ +within REFPROP2Modelica; +package Testers +end Testers; diff --git a/Testers/package.order b/Testers/package.order new file mode 100644 index 0000000..6804795 --- /dev/null +++ b/Testers/package.order @@ -0,0 +1,6 @@ +PentaneTester +R410mixTester +PropsMixtureTwo +PropsMixture +PropsPureSubstance +Water_MixtureTwoPhase_pT diff --git a/Water_MixtureTwoPhase_pT/package.order b/Water_MixtureTwoPhase_pT/package.order deleted file mode 100644 index 9510fbd..0000000 --- a/Water_MixtureTwoPhase_pT/package.order +++ /dev/null @@ -1,20 +0,0 @@ -M_H2O -BaseProperties -specificEnthalpy_pTX -temperature_phX -ThermodynamicState -dewEnthalpy -bubbleEnthalpy -saturationTemperature -dynamicViscosity -specificEntropy -specificEnthalpy_ps -setState_psX -temperature -density -setState_pTX -specificEntropy_pTX -thermalConductivity -specificHeatCapacityCp -saturationPressure -specificHeatCapacityCv diff --git a/_wrapper/v0.5/REFPROP_wrapper.lib b/_wrapper/v0.5/REFPROP_wrapper.lib index bc7f7bc3f7ed2de7b75c6dce583b409bd1e7c2c3..4c9870c7f80251be5a14ab06c9faea8f83e0a93c 100644 GIT binary patch delta 31 mcmeC$!PK^cX@jDQK#;3jK#+fck#BxVYEEWy;$~BotK|T$&kIlh delta 35 qcmZqM!PK>bX@jDQh;M32W@1Qren3WIajI`-MM-H<>SjZgtK|UjGY#7S diff --git a/_wrapper/v0.6/Makefile b/_wrapper/v0.6/Makefile index 0992eea..068366e 100644 --- a/_wrapper/v0.6/Makefile +++ b/_wrapper/v0.6/Makefile @@ -1,7 +1,7 @@ # ============================================================================ # Name : Makefile # Author : Jorrit Wronski (jowr@mek.dtu.dk) -# Version : 0.6 +# Version : 0.6.1 # Copyright : Use and modify at your own risk. # Description : Makefile for Refprop from Fortran and C++ tests. # ============================================================================ @@ -21,7 +21,7 @@ LN := ln -sf # used for the output MAJORVERSION =0 -MINORVERSION =6 +MINORVERSION =6.1 THENAME =refprop_wrapper LIBRARYEXTENSION =.so THETEST =refpropwrappertest diff --git a/_wrapper/v0.6/bin/librefprop_wrapper.so b/_wrapper/v0.6/bin/librefprop_wrapper.so new file mode 100644 index 0000000000000000000000000000000000000000..7d49ccc1c7028ede607481095349607106893fad GIT binary patch literal 249080 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ⓈI+KY`lMtiAo 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 WB2}e~=)Y7eV;@oDi{el$YX1Sr&eHk- literal 0 HcmV?d00001 diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp index 1426c1e..76ce0fc 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ b/_wrapper/v0.6/src/refprop_wrapper.cpp @@ -77,6 +77,8 @@ SETUPdll_POINTER SETUPlib = NULL; XMASSdll_POINTER XMASSlib = NULL; XMOLEdll_POINTER XMOLElib = NULL; +THERM2dll_POINTER THERM2lib = NULL; + /* * Just a helper function control the output of @@ -164,8 +166,8 @@ int flushSaturation() { */ double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, - dhjt, dZ, dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, - ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn; + dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, + ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn, dddhp; int flushProperties(){ dt=noValue; dp=noValue; @@ -185,7 +187,7 @@ int flushProperties(){ dwliq=noValue; dwvap=noValue; dhjt=noValue; - dZ=noValue; + dZ[0]=noValue; dA=noValue; dG=noValue; dxkappa=noValue; @@ -202,6 +204,7 @@ int flushProperties(){ deta=noValue; dtcx=noValue; dstn=noValue; + dddhp=noValue; if (debug) printf ("Finished flushing normal fluid properties.\n"); return flushSaturation(); } @@ -374,6 +377,7 @@ int loadLibrary(std::string pathToRefprop, char* error) { XMOLElib = (XMOLEdll_POINTER) RefpropdllInstance->getSymbol(XMOLEdll_NAME); SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); // + THERM2lib = (THERM2dll_POINTER) RefpropdllInstance->getSymbol(THERM2dll_NAME); if (debug) printf ("Library instance successfully loaded.\n"); } else { // library was already loaded if (debug) printf ("Library instance already, not doing anything.\n"); @@ -689,6 +693,14 @@ double getTCX_modelica(){ return dtcx; } +// Derivative of density with respect to enthalpy at constant pressure +double getDDHP_modelica(){ + return dddhp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +} +// Derivative of density with respect to pressure at constant enthalpy +double getDDPH_modelica(){ + return ddddp*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J +} /* @@ -739,10 +751,62 @@ double getValue(std::string out) { if (deta!=noValue) return getETA_modelica(); } else if ( 0 == Poco::icompare(out, "l") ) { if (dtcx!=noValue) return getTCX_modelica(); + } else if ( 0 == Poco::icompare(out, "ddhp") ) { + if (dddhp!=noValue) return getDDHP_modelica(); + } else if ( 0 == Poco::icompare(out, "ddph") ) { + if (ddddp!=noValue) return getDDPH_modelica(); } return noValue; } +/* + * Improvised derivative computing. These functions are called + * after properties were calculated. Hence, we have density and + * pressure available. REFPROP is formulated with explicit d and + * T it should not take too much extra time. + */ +double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; +double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; +int setDensDeriv(bool debug, long lerr, char* errormsg){ + double rho,T; + rho = getValue("d"); + T = getValue("T"); + if ((rho!=noValue)&&(T!=noValue)) { // call explicit function + // get derivative of density with respect to pressure from Refprop library + //if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); + //THERM2lib (dt,dd,dxmol,dp,de,dh,ds,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); + deltaP = 1.; + pLow = dp - 0.5*deltaP; + pHigh = dp + 0.5*deltaP; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); + PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); + PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); + ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); + + // get derivative of density with respect to enthalpy numerically + deltaH = 20.; + hLow = dh - 0.5*deltaH; + hHigh = dh + 0.5*deltaH; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); + PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); + PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); + dddhp = (rhoHigh-rhoLow) / (hHigh-hLow); + } else { // We have a problem! + printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); + } + return 0; +} + int updateProps(double *props, long lerr){ //ASSIGN VALUES TO RETURN ARRAY props[0] = lerr;//error code @@ -759,8 +823,10 @@ int updateProps(double *props, long lerr){ props[11] = getCV_modelica(); props[12] = getCP_modelica(); props[13] = getW_modelica(); //speed of sound - props[14] = getWML_modelica(); - props[15] = getWMV_modelica(); + props[14] = getDDHP_modelica(); //ddhp + props[15] = getDDPH_modelica(); //ddph + props[16] = getWML_modelica(); + props[17] = getWMV_modelica(); double dxlkg[ncmax], dxvkg[ncmax]; @@ -769,8 +835,8 @@ int updateProps(double *props, long lerr){ for (int dim=0; dim Contact -Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" - -")); -end MediaTwoPhaseMixture; +within ; +package REFPROP2Modelica +// constant String REFPROP_PATH = "d:\\Program Files (x86)\\REFPROP\\"; + constant String REFPROP_PATH = "/opt/refprop/"; + + + annotation (version="0.2", uses(Modelica(version="3.2")), + Documentation(info=" +

+Documentation is found in the packages. Installation directions are found in both REFPROP packages. +

+

Contact for original implementation:

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +", + revisions=" + +")); +end REFPROP2Modelica; diff --git a/package.order b/package.order index 99b206b..0a82484 100644 --- a/package.order +++ b/package.order @@ -1,6 +1,4 @@ -REFPROP_PATH -Examples -PartialMixtureTwoPhaseMedium -REFPROPMedium -Water_MixtureTwoPhase_pT -REFPROPMediumPureSubstance +REFPROP_PATH +Media +Testers +Interfaces diff --git a/readme.md b/readme.md index 3c97886..b490793 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ If you only want to run the wrapper without compiling it from source, you can us > For Windows, please follow these instructions > -> 1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. +> 1. After downloading and unzipping rename folder containing these files to `REFPROP2Modelica`. > 2. Double click on `_wrapper\v0.6\Makefile.bat` > 3. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; > @@ -18,7 +18,7 @@ If you only want to run the wrapper without compiling it from source, you can us ### Linux For installing on a Linux machine, please follow these instructions -1. After downloading and unzipping rename folder containing these files to `MediaTwoPhaseMixture`. +1. After downloading and unzipping rename folder containing these files to `REFPROP2Modelica`. 2. Open a command prompt in `_wrapper/v0.6/` and run `sudo make install_static`. 3. Make sure to have the shared library `librefprop.so` available in the same directory as the `fluids` folder. You might want to check https://github.com/jowr/librefprop.so for details. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; From 0ea4faa3007fe05bf66bf89764a6ae8b7a6df7d4 Mon Sep 17 00:00:00 2001 From: jowr Date: Mon, 25 Feb 2013 16:52:38 +0100 Subject: [PATCH 20/57] Included derivatives. Numerical versions for drhodh_p and drhodp_h. Added some more, but tests are missing. --- ...Two.mo => PartialMixtureTwoPhaseMedium.mo} | 58 +- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 136 +++-- Interfaces/package.order | 2 +- Testers/PentaneTester.mo | 42 +- Testers/R410mixTester.mo | 2 +- Testers/Water_MixtureTwoPhase_pT.mo | 2 +- _wrapper/v0.6/bin/librefprop_wrapper.so | Bin 249080 -> 306063 bytes _wrapper/v0.6/src/refprop_wrapper.cpp | 509 +++++++++++++++--- _wrapper/v0.6/src/refprop_wrapper.h | 26 +- _wrapper/v0.6/src/refpropwrappertest.cpp | 56 +- 10 files changed, 632 insertions(+), 201 deletions(-) rename Interfaces/{PartialMixtureTwoPhaseMediumTwo.mo => PartialMixtureTwoPhaseMedium.mo} (96%) diff --git a/Interfaces/PartialMixtureTwoPhaseMediumTwo.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo similarity index 96% rename from Interfaces/PartialMixtureTwoPhaseMediumTwo.mo rename to Interfaces/PartialMixtureTwoPhaseMedium.mo index 7680773..5132d7d 100644 --- a/Interfaces/PartialMixtureTwoPhaseMediumTwo.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -1,5 +1,5 @@ within REFPROP2Modelica.Interfaces; -partial package PartialMixtureTwoPhaseMediumTwo +partial package PartialMixtureTwoPhaseMedium "Template class for two phase medium of a mixture of substances " extends Modelica.Media.Interfaces.PartialMixtureMedium; constant Boolean smoothModel = false @@ -7,6 +7,8 @@ partial package PartialMixtureTwoPhaseMediumTwo constant Boolean onePhase = false "true if the (derived) model should never be called with two-phase inputs"; + //constant Real minValue = 1e-6; + constant FluidConstants mixtureFluidConstants( iupacName = "mixture", casRegistryNumber = "mixture", @@ -58,16 +60,12 @@ redeclare replaceable record extends ThermodynamicState "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; //PrandtlNumber Pr "prandtl number"; //Temperature T "temperature"; - VelocityOfSound a "velocity of sound"; + VelocityOfSound w(min=1e-8) "velocity of sound"; //Modelica.SIunits.CubicExpansionCoefficient beta //"isobaric expansion coefficient"; - SpecificHeatCapacity cp "specific heat capacity cp"; - SpecificHeatCapacity cv "specific heat capacity cv"; - Density d "density"; - DerDensityByEnthalpy ddhp - "derivative of density wrt enthalpy at constant pressure"; - DerDensityByPressure ddph - "derivative of density wrt pressure at constant enthalpy"; + SpecificHeatCapacity cp(min=1e-8) "specific heat capacity cp"; + SpecificHeatCapacity cv(min=1e-8) "specific heat capacity cv"; + Density d(min=1e-8) "density"; //DynamicViscosity eta "dynamic viscosity"; SpecificEnthalpy h "specific enthalpy"; //Modelica.SIunits.Compressibility kappa "compressibility"; @@ -81,7 +79,7 @@ end ThermodynamicState; replaceable record SaturationProperties "Saturation properties of two phase medium" extends Modelica.Icons.Record; - Temperature Tsat "saturation temperature"; + Temperature Tsat(min=1e-8) "saturation temperature"; // Real dTp "derivative of Ts wrt pressure"; // DerDensityByPressure ddldp "derivative of dls wrt pressure"; // DerDensityByPressure ddvdp "derivative of dvs wrt pressure"; @@ -91,7 +89,7 @@ end ThermodynamicState; // Density dv "density at dew line (for pressure ps)"; // SpecificEnthalpy hl "specific enthalpy at bubble line (for pressure ps)"; // SpecificEnthalpy hv "specific enthalpy at dew line (for pressure ps)"; - AbsolutePressure psat "saturation pressure"; + AbsolutePressure psat(min=1e-8) "saturation pressure"; // SurfaceTension sigma "surface tension"; // SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; // SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; @@ -102,19 +100,19 @@ end ThermodynamicState; end SaturationProperties; redeclare replaceable model extends BaseProperties( - p(stateSelect = if preferredMediumStates and + p(min=1e-8,stateSelect = if preferredMediumStates and (basePropertiesInputChoice == InputChoice.phX or basePropertiesInputChoice == InputChoice.pTX or basePropertiesInputChoice == InputChoice.psX) then StateSelect.prefer else StateSelect.default), - T(stateSelect = if preferredMediumStates and + T(min=1e-8,stateSelect = if preferredMediumStates and (basePropertiesInputChoice == InputChoice.pTX or basePropertiesInputChoice == InputChoice.dTX) then StateSelect.prefer else StateSelect.default), h(stateSelect = if preferredMediumStates and basePropertiesInputChoice == InputChoice.phX then StateSelect.prefer else StateSelect.default), - d(stateSelect = if preferredMediumStates and + d(min=1e-8,stateSelect = if preferredMediumStates and basePropertiesInputChoice == InputChoice.dTX then StateSelect.prefer else StateSelect.default)) import REFPROP2Modelica.Interfaces.MixtureInputChoice; @@ -131,7 +129,7 @@ redeclare replaceable model extends BaseProperties( SaturationProperties sat "saturation property record"; equation MM = state.molarMass; - R = Modelica.Constants.R/MM; + R = Modelica.Constants.R/max(1e-8,MM); if (onePhase or (basePropertiesInputChoice == InputChoice.pTX)) then phaseInput = 1 "Force one-phase property computation"; else @@ -187,7 +185,7 @@ equation T = temperature(state); end if; // Compute the internal energy - u = h - p/d; + u = h - p/max(1e-8,d); // Compute the saturation properties record sat = setSat_pX(state.p,state.X); // Event generation for phase boundary crossing @@ -920,20 +918,20 @@ end temperature; annotation(Documentation(info="")); end surfaceTension; - annotation(Documentation(info=""), - Documentation(info=" +type DerPressureByDensity = Real (unit="m2/s2"); +type DerDerPressureByDensityByDensity = Real (unit="(m5)/(kg.s2)"); +type DerPressureByTemperature = Real (unit="kg/(K.m.s2)"); +//type DerDensityByTemperature = Real (unit="kg/(m3.K)"); +//type DerDensityByPressure = Real (unit="s2/m2"); +type DerDerPressureByTemperatureByTemperature = Real (unit="kg/(m.s2.K2)"); +type DerDerPressureByTemperatureByDensity = Real (unit="(m2)/(s2.K)"); + +type DerEnthalpyByDensity = Real (unit="J.m3/kg"); +//type DerEnthalpyByPressure = Real (unit="J.m.s2/kg"); +type DerEnthalpyByTemperature = Real (unit="J/K"); + + annotation(Documentation(info="

PartialMixtureTwoPhaseMedium

- This is a template for two phase medium of a mixture of substances and is used by REFPROPMedium.
- It has been created by merging PartialMixtureMedium and PartialTwoPhaseMedium from Modelica.Media.Interfaces.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de ")); -end PartialMixtureTwoPhaseMediumTwo; +end PartialMixtureTwoPhaseMedium; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index d962d1d..710d0e9 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -1,10 +1,11 @@ within REFPROP2Modelica.Interfaces; partial package REFPROPMixtureTwoPhaseMedium "Two-phase mixture medium (properties supplied by REFPROP library)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMediumTwo( + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( mediumName="REFPROP Medium", final reducedX=true, final singleState=false, + final smoothModel=true, reference_X=cat( 1, fill(0, nX - 1), @@ -41,9 +42,16 @@ partial package REFPROPMixtureTwoPhaseMedium //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() extends Modelica.Icons.Function; protected - Real[18 + 2*nX] props; + Real[16 + 2*nX] props; + Real[21] ders; + Real[3] trns; String errormsg=StrJoin(fill("xxxx", 64), "") "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; + // initial algorithm + // props :=fill(1, (16 + 2*nX)); + // ders :=fill(1, 19); + // trns :=fill(1, 3); + end partialREFPROP; function getProp_REFPROP @@ -51,6 +59,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String what2calc; input String statevars; input String fluidnames; + input Real[:] ders; + input Real[:] trns; input Real[:] props; input Real statevar1; input Real statevar2; @@ -63,6 +73,8 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevars, fluidnames, + ders, + trns, props, statevar1, statevar2, @@ -92,6 +104,8 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevars, fluidnames, + ders, + trns, props, statevar1, statevar2, @@ -108,6 +122,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String what2calc; input String statevar; input String fluidnames; + input Real[:] ders; + input Real[:] trns; input Real[:] props; input Real statevarval; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; @@ -118,6 +134,8 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevar, fluidnames, + ders, + trns, props, statevarval, X, @@ -142,6 +160,8 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevar, fluidnames, + ders, + trns, props, statevarval, X, @@ -161,13 +181,45 @@ redeclare record extends ThermodynamicState // Density d_l "density of liquid phase"; // Density d_g "density of gaseous phase"; // MassFraction x "void fraction"; -// SpecificInternalEnergy u "Specific energy"; +// SpecificInternalEnergy u "Specific energy"; -// MolarMass MM_l "Molar Mass of liquid phase"; +// MolarMass MM_l "Molar Mass of liquid phase"; // MolarMass MM_g "Molar Mass of gas phase"; // MassFraction X_l[nX] // "Composition of liquid phase (Mass fractions in kg/kg)"; // MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; +// DerDensityByEnthalpy ddhp +// "derivative of density wrt enthalpy at constant pressure"; +// DerDensityByPressure ddph +// "derivative of density wrt pressure at constant enthalpy"; + + Real hjt "isenthalpic Joule-Thompson coefficient [K/Pa]"; + Modelica.SIunits.SpecificHelmholtzFreeEnergy a "Helmholtz energy"; + Modelica.SIunits.SpecificGibbsFreeEnergy f "Gibbs free energy"; + Modelica.SIunits.IsothermalCompressibility kappa "isothermal compressibility"; + IsobaricExpansionCoefficient beta + "volume expansivity (= 1/V dV/dT = -1/rho dD/dT)"; + + DerPressureByDensity dpdrho_T; + DerDerPressureByDensityByDensity d2pdrho2_T; + DerPressureByTemperature dpdT_rho; + DerDensityByTemperature drhodT_p; + DerDensityByPressure drhodp_T; + DerDerPressureByTemperatureByTemperature d2pdT2_rho; + DerDerPressureByTemperatureByDensity d2pdTdrho; + DerEnthalpyByTemperature dhdT_rho "dH/dT at constant density"; + DerEnthalpyByTemperature dhdT_p "dH/dT at constant pressure"; + DerEnthalpyByDensity dhdrho_T "dH/drho at constant temperature"; + DerEnthalpyByDensity dhdrho_p "dH/drho at constant pressure"; + DerEnthalpyByPressure dhdp_T "dH/dP at constant temperature"; + DerEnthalpyByPressure dhdp_rho "dH/dP at constant density"; + + DerDensityByEnthalpy drhodh_p "drho/dh at constant pressure"; + DerDensityByPressure drhodp_h "drho/dp at constant enthalpy"; + + DynamicViscosity eta "dynamic viscosity"; + ThermalConductivity lambda "thermal conductivity"; + end ThermodynamicState; // redeclare record extends ThermodynamicState @@ -303,9 +355,11 @@ end ThermodynamicState; algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); getProp_REFPROP( - "", + "u", statevars, fluidnames, + ders, + trns, props, statevar1, statevar2, @@ -328,18 +382,36 @@ end ThermodynamicState; s=props[11], cv=props[12], cp=props[13], - a=props[14], - ddhp=props[15], - ddph=props[16], - phase=if (props[8] > 0 and props[8] < 1) then 2 else 1); - // u=props[9], - // d_l=props[6], - // d_g=props[7], - // x=min(max(props[8], 0), 1), - // MM_l=props[17], - // MM_g=props[18], - // X_l=props[19:18 + nX], - // X_g=props[19 + nX:18 + 2*nX], + w=props[14], + phase=if (props[8] > 0 and props[8] < 1) then 2 else 1, + hjt=ders[2], + a=ders[3], + f=ders[4], + kappa=ders[5], + beta=ders[6], + dpdrho_T=ders[7], + d2pdrho2_T=ders[8], + dpdT_rho=ders[9], + drhodT_p=ders[10], + drhodp_T=ders[11], + d2pdT2_rho=ders[12], + d2pdTdrho=ders[13], + dhdT_rho=ders[14], + dhdT_p=ders[15], + dhdrho_T=ders[16], + dhdrho_p=ders[17], + dhdp_T=ders[18], + dhdp_rho=ders[19], + drhodh_p=ders[20], + drhodp_h=ders[21], + eta=trns[2], + lambda=trns[3]); + + if debugmode then + Modelica.Utilities.Streams.print("Running state set to p,T,d,h,s (" + + String(state.p) + "," + String(state.T) + "," + String(state.d) + "," + String(state.h) + "," + String(state.s) + ")"); + end if; + end setState; function setState_dsX "Calculates medium properties from d,s,X" @@ -1698,20 +1770,6 @@ end ThermodynamicState; phase))); end temperature_psX; - redeclare function extends thermalConductivity - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running thermalConductivity"); - end if; - lambda := getProp_REFPROP_check( - "l", - "Td", - state.T, - state.d, - state.X, - state.phase); - end thermalConductivity; - // redeclare function vapourQuality "Return vapour quality" // input ThermodynamicState state "Thermodynamic state record"; // output MassFraction x "Vapour quality"; @@ -1730,18 +1788,20 @@ end ThermodynamicState; cv := state.cv; end specificHeatCapacityCv; + redeclare function extends thermalConductivity + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running thermalConductivity"); + end if; + lambda := state.lambda; + end thermalConductivity; + redeclare function extends dynamicViscosity algorithm if debugmode then Modelica.Utilities.Streams.print("Running dynamicViscosity"); end if; - eta := getProp_REFPROP_check( - "v", - "Td", - state.T, - state.d, - state.X, - state.phase); + eta := state.eta; end dynamicViscosity; function StrJoin "Converts an Array of Strings into a string separated by |" diff --git a/Interfaces/package.order b/Interfaces/package.order index 048dc0e..475bb51 100644 --- a/Interfaces/package.order +++ b/Interfaces/package.order @@ -1,4 +1,4 @@ PureSubstanceInputChoice MixtureInputChoice REFPROPMixtureTwoPhaseMedium -PartialMixtureTwoPhaseMediumTwo +PartialMixtureTwoPhaseMedium diff --git a/Testers/PentaneTester.mo b/Testers/PentaneTester.mo index 40aa369..5d59117 100644 --- a/Testers/PentaneTester.mo +++ b/Testers/PentaneTester.mo @@ -1,9 +1,9 @@ within REFPROP2Modelica.Testers; model PentaneTester "Evaporation of pentane at 1 bar" -package Medium = REFPROP2Modelica.Media.Pentane ( debugmode=true); +package Medium = REFPROP2Modelica.Media.Pentane (debugmode=true); // ",final explicitVars = "pd""; //package Medium = REFPROP2Modelica.REFPROPMedium(final substanceNames={"CO2","water"}); - Medium.BaseProperties props; + Medium.BaseProperties props(h(start=300e3),d(start=1)); // Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); /* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); Modelica.SIunits.Density d; @@ -21,9 +21,43 @@ Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.stat // Real q = Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); // Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); +Real drhodtime_num; +Real drhodtime_ana; + Real factor1; + Real factor2; + Real check1; + Real check2; + Real deltap; + Real deltah; + Real ddddp_num; + Real ddddp_num_RP; + Real ddddp_ana; + Real ddddh_num; + Real ddddh_num_RP; + Real ddddh_ana; equation - props.p = 1e5; - props.h = -1e5+time*6e5; + deltap = 5; + deltah = 5; + props.p = 10e5;//1e5+3*time*4e5*(sin(20*time)+1)*0.5; + props.h = -3e5+time*7e5; + + // get derivatives for checking + factor1 = der(props.p); + factor2 = der(props.h); + + drhodtime_num = ddddp_num * factor1 + ddddh_num * factor2; + ddddp_num = (Medium.density_phX(props.p+0.5*deltap,props.h,props.X)-Medium.density_phX(props.p-0.5*deltap,props.h,props.X)) / deltap; + ddddh_num = (Medium.density_phX(props.p,props.h+0.5*deltah,props.X)-Medium.density_phX(props.p,props.h-0.5*deltah,props.X)) / deltah; + + drhodtime_ana = ddddp_ana * factor1 + ddddh_ana * factor2; + -1 = ddddp_ana * 1/(props.state.dhdp_rho) * props.state.dhdrho_p; + ddddh_ana * props.state.dhdrho_p= 1; + + check1 = ddddp_num - props.state.drhodp_h; + check2 = ddddh_num - props.state.drhodh_p; + + ddddh_num_RP = props.state.drhodh_p "drho/dh at constant pressure"; + ddddp_num_RP = props.state.drhodp_h "drho/dp at constant enthalpy"; // props.s = 5.88105; // props.T = 400; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo index d85be9d..c28c7c3 100644 --- a/Testers/R410mixTester.mo +++ b/Testers/R410mixTester.mo @@ -9,7 +9,7 @@ package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); equation props.p = 101325; h = Medium.dewEnthalpy(props.sat); - props.h = h; + props.h = h+0.2*h*0.5*(sin(5*time)+1); props.d = d; props.Xi = {0.697615}; end R410mixTester; diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo index 3d8560f..deb20fd 100644 --- a/Testers/Water_MixtureTwoPhase_pT.mo +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; package Water_MixtureTwoPhase_pT "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMediumTwo( + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( final mediumName="TwoPhaseMixtureWater", final substanceNames={"water"}, final reducedX = true, diff --git a/_wrapper/v0.6/bin/librefprop_wrapper.so b/_wrapper/v0.6/bin/librefprop_wrapper.so index 7d49ccc1c7028ede607481095349607106893fad..414a73ae4c294134877bbfacde24368a9c2d0add 100644 GIT binary patch literal 306063 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 BBq;y@ literal 249080 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ⓈI+KY`lMtiAo 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 WB2}e~=)Y7eV;@oDi{el$YX1Sr&eHk- diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp index 76ce0fc..a4d7888 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ b/_wrapper/v0.6/src/refprop_wrapper.cpp @@ -1,16 +1,15 @@ /* - wrapper file for refprop. - - Compatible to the Modelica interface developed by - Henning Francke (francke@gfz-potsdam.de) and his first - wrapper class that you can find in the folder with - version 0.5 for Windows systems. - - Partly based on the Refprop wrapper used in CoolProp by - Ian Bell (ian.h.bell@gmail.com) - http://coolprop.sourceforge.net/ - - Changes to produce this file by Jorrit Wronski (jowr@mek.dtu.dk) + This is a wrapper file for the Refprop library. It does not include + any functionality besides providing the connection to Refprop. + + The current version was developed by Jorrit Wronski (jowr@mek.dtu.dk) + based on Henning Francke's (francke@gfz-potsdam.de) wrapper. A little + inspiration also came from Ian Bell's (ian.h.bell@gmail.com) wrapper + used in CoolProp - http://coolprop.sourceforge.net/ + Compatible to the Modelica interface developed by Henning Francke + (francke@gfz-potsdam.de) and his first wrapper class that you can + find in the folder with version 0.5 for Windows systems. */ /* @@ -78,6 +77,7 @@ XMASSdll_POINTER XMASSlib = NULL; XMOLEdll_POINTER XMOLElib = NULL; THERM2dll_POINTER THERM2lib = NULL; +DHD1dll_POINTER DHD1lib = NULL; /* @@ -167,7 +167,12 @@ int flushSaturation() { double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, - ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn, dddhp; + ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn; + +double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; + +double ddddp_h_num, ddddh_p_num; // get numerical derivatives + int flushProperties(){ dt=noValue; dp=noValue; @@ -204,7 +209,17 @@ int flushProperties(){ deta=noValue; dtcx=noValue; dstn=noValue; - dddhp=noValue; + + ddhdt_d=noValue; + ddhdt_p=noValue; + ddhdd_t=noValue; + ddhdd_p=noValue; + ddhdp_t=noValue; + ddhdp_d=noValue; + + ddddp_h_num=noValue; + ddddh_p_num=noValue; + if (debug) printf ("Finished flushing normal fluid properties.\n"); return flushSaturation(); } @@ -378,6 +393,8 @@ int loadLibrary(std::string pathToRefprop, char* error) { SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); // THERM2lib = (THERM2dll_POINTER) RefpropdllInstance->getSymbol(THERM2dll_NAME); + DHD1lib = (DHD1dll_POINTER) RefpropdllInstance->getSymbol(DHD1dll_NAME); + if (debug) printf ("Library instance successfully loaded.\n"); } else { // library was already loaded if (debug) printf ("Library instance already, not doing anything.\n"); @@ -693,13 +710,74 @@ double getTCX_modelica(){ return dtcx; } +double getHJT_modelica() { // isenthalpic Joule-Thompson coefficient [K/kPa]/1000Pa*kPa = K/Pa + return dhjt/1000; +} +//double* getZ_modelica() { // compressibility factor (= PV/RT) [dimensionless] +// return dZ; +//} +double getA_modelica() { // Helmholtz energy [J/mol] + return dA/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getG_modelica() { // Gibbs free energy [J/mol] + return dG/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getXKAPPA_modelica() { // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/kPa] /1000Pa*kPa = 1/Pa + return dxkappa / 1000. ; +} +double getBETA_modelica() { // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + return dbeta; +} +double getDPDD_modelica() { // derivative dP/drho [kPa-L/mol] * 1000Pa/kPa * mol/g = Pa.m3 / kg + return ddpdd * 1000. / dwm; +} +double getD2PDD2_modelica() { // derivative d^2P/drho^2 [kPa-L^2/mol^2] * 1000Pa/kPa * mol/g * mol/g = Pa m6 / kg2 + return dd2pdd2 * 1000. / dwm / dwm; +} +double getDPDT_modelica() { // derivative dP/dT [kPa/K] * 1000Pa/kPa = Pa/K + return ddpdt * 1000.; +} +double getDDDT_modelica() { // derivative drho/dT [mol/(L-K)] * g/mol = kg/m3 / K + return ddddt * dwm; +} +double getDDDP_modelica() { // derivative drho/dP [mol/(L-kPa)] + return ddddp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +} +double getD2PDT2_modelica() { // derivative d2P/dT2 [kPa/K^2] * 1000Pa/kPa = Pa/K2 + return dd2pdt2 * 1000.; +} +double getD2PDTD_modelica() { // derivative d2P/dTd(rho) [J/mol-K] / g/mol * 1000g/kg = J/kg.K + return dd2pdtd/dwm*1000.; +} + + +double get_dhdt_d_modelica() { //dH/dT at constant density [J/(mol-K)] / g/mol * 1000g/kg = J/kg.K + return ddhdt_d/dwm*1000; +} +double get_dhdt_p_modelica() { //dH/dT at constant pressure [J/(mol-K)] + return ddhdt_p/dwm*1000; +} +double get_dhdd_t_modelica() { //dH/drho at constant temperature [(J/mol)/(mol/L)] * mol/g * 1000g/kg / g/mol = (J/kg) / (kg/m3) + return ddhdd_t /dwm*1000. / dwm; +} +double get_dhdd_p_modelica() { //dH/drho at constant pressure [(J/mol)/(mol/L)] + return ddhdd_p /dwm*1000. / dwm; +} +double get_dhdp_t_modelica() { //dH/dP at constant temperature [J/(mol-kPa)] /dwm*1000. / (1000Pa/kPa) = J/kg.Pa + return ddhdp_t / dwm; +} +double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] + return ddhdp_d / dwm; +} + +// Numerical derivatives // Derivative of density with respect to enthalpy at constant pressure -double getDDHP_modelica(){ - return dddhp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +double get_dddh_p_num_modelica(){ + return ddddh_p_num*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J } // Derivative of density with respect to pressure at constant enthalpy -double getDDPH_modelica(){ - return ddddp*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J +double get_dddp_h_num_modelica(){ + return ddddp_h_num*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) } @@ -751,62 +829,319 @@ double getValue(std::string out) { if (deta!=noValue) return getETA_modelica(); } else if ( 0 == Poco::icompare(out, "l") ) { if (dtcx!=noValue) return getTCX_modelica(); - } else if ( 0 == Poco::icompare(out, "ddhp") ) { - if (dddhp!=noValue) return getDDHP_modelica(); - } else if ( 0 == Poco::icompare(out, "ddph") ) { - if (ddddp!=noValue) return getDDPH_modelica(); } return noValue; } -/* - * Improvised derivative computing. These functions are called - * after properties were calculated. Hence, we have density and - * pressure available. REFPROP is formulated with explicit d and - * T it should not take too much extra time. - */ -double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; -double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; -int setDensDeriv(bool debug, long lerr, char* errormsg){ - double rho,T; - rho = getValue("d"); - T = getValue("T"); - if ((rho!=noValue)&&(T!=noValue)) { // call explicit function - // get derivative of density with respect to pressure from Refprop library - //if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); - //THERM2lib (dt,dd,dxmol,dp,de,dh,ds,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); - deltaP = 1.; - pLow = dp - 0.5*deltaP; - pHigh = dp + 0.5*deltaP; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); - PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); - PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); - ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); - - // get derivative of density with respect to enthalpy numerically - deltaH = 20.; - hLow = dh - 0.5*deltaH; - hHigh = dh + 0.5*deltaH; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); - PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); - PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); - dddhp = (rhoHigh-rhoLow) / (hHigh-hLow); +///* +// * Improvised derivative computing. These functions are called +// * after properties were calculated. Hence, we have density and +// * pressure available. REFPROP is formulated with explicit d and +// * T it should not take too much extra time. +// */ +//double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; +//double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; +//int setExtra(bool debug, long lerr, char* errormsg){ +// double rho,T; +// rho = getValue("d"); +// T = getValue("T"); +// if ((rho!=noValue)&&(T!=noValue)) { // call explicit function +// // get derivative of density with respect to pressure from Refprop library +// if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); +// THERM2lib (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); +//// deltaP = 1.; +//// pLow = dp - 0.5*deltaP; +//// pHigh = dp + 0.5*deltaP; +//// rhoLow = 0; +//// rhoHigh = 0; +//// //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); +//// PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); +//// PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +//// if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); +//// ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); +// +// // get derivative of density with respect to enthalpy numerically +// deltaH = 20.; +// hLow = dh - 0.5*deltaH; +// hHigh = dh + 0.5*deltaH; +// rhoLow = 0; +// rhoHigh = 0; +// //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); +// PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); +// PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +// if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); +// ddddh = (rhoHigh-rhoLow) / (hHigh-hLow); +// } else { // We have a problem! +// printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); +// } +// return 0; +//} + +//int updateExtra(double *der, long lerr){ +//// c inputs: +//// c t--temperature [K] +//// c rho--molar density [mol/L] +//// c x--composition [array of mol frac] +//// c outputs: +//// c p--pressure [kPa] +//// c e--internal energy [J/mol] +//// c h--enthalpy [J/mol] +//// c s--entropy [J/mol-K] +//// c Cv--isochoric heat capacity [J/mol-K] +//// c Cp--isobaric heat capacity [J/mol-K] +//// c w--speed of sound [m/s] +//// c Z +//// c hjt +//// c A +//// c G +//// c xkappa +//// c beta +//// c dPdrho +//// c d2PdD2 +//// c dPT +//// c drhodT +//// c drhodP +//// c d2PT2 +//// c d2PdTD +//// c sparei--2 space holders for possible future properties +// +// +//// subroutine DHD1(t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d) +////c +////c compute partial derivatives of enthalpy w.r.t. t, p, or rho at constant +////c t, p, or rho as a function of temperature, density, and composition +////c +////c inputs: +////c t--temperature [K] +////c rho--molar density [mol/L] +////c x--composition [array of mol frac] +////c outputs: +////c get_dhdt_d_modelica(); --dH/dT at constant density [J/(mol-K)] +////c get_dhdt_p_modelica(); --dH/dT at constant pressure [J/(mol-K)] +////c get_dhdd_t_modelica(); --dH/drho at constant temperature [(J/mol)/(mol/L)] +////c get_dhdd_p_modelica(); --dH/drho at constant pressure [(J/mol)/(mol/L)] +////c get_dhdp_t_modelica(); --dH/dP at constant temperature [J/(mol-kPa)] +////c get_dhdp_d_modelica(); --dH/dP at constant density [J/(mol-kPa)] +// +//// double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, +//// ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, +//// + + +// +// +// +// +// getDDDH +// +// +// +// +//// THERM2lib (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); +// +// //ASSIGN VALUES TO RETURN ARRAY +// der[0] = lerr;//error code +// der[1] = getP_modelica(); //pressure in Pa +// der[2] = getT_modelica(); //Temperature in K +// der[3] = getWM_modelica(); //molecular weight +// der[4] = getD_modelica(); //density +// der[5] = getDL_modelica(); //density of liquid phase +// der[6] = getDV_modelica(); //density of liquid phase +// der[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) +// der[8] = getE_modelica(); //internal energy +// der[9] = getH_modelica(); //specific enthalpy +// der[10] = getS_modelica(); //specific entropy +// der[11] = getCV_modelica(); // heat capacity +// der[12] = getCP_modelica(); // heat capacity +// der[13] = getW_modelica(); //speed of sound +// der[14] = getDDDH_modelica(); //ddhp +// der[15] = getDDDP_modelica(); //ddph +// der[16] = getWML_modelica(); +// der[17] = getWMV_modelica(); +// +// double dxlkg[ncmax], dxvkg[ncmax]; +// +// +// return 0; +//} + + + +int updateDers(double *ders, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + ders[0] = lerr;//error code + ders[1] = getHJT_modelica(); // isenthalpic Joule-Thompson coefficient [K/Pa] + ders[2] = getA_modelica(); // Helmholtz energy [J/kg] + ders[3] = getG_modelica(); // Gibbs free energy [J/kg] + ders[4] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[5] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[6] = getDPDD_modelica(); // derivative dP/drho [Pa-m3/kg] + ders[7] = getD2PDD2_modelica(); // derivative d^2P/drho^2 [Pa-m6/kg2] + ders[8] = getDPDT_modelica(); // derivative dP/dT [Pa/K] + ders[9] = getDDDT_modelica(); // derivative drho/dT [kg/(m3-K)] + ders[10] = getDDDP_modelica(); // derivative drho/dP [kg/(m3-kPa)] + ders[11] = getD2PDT2_modelica(); // derivative d2P/dT2 [Pa/K2] + ders[12] = getD2PDTD_modelica(); // derivative d2P/dTd(rho) [J/kg-K] + ders[13] = get_dhdt_d_modelica(); // dH/dT at constant density [J/(kg-K)] + ders[14] = get_dhdt_p_modelica(); // dH/dT at constant pressure [J/(kg-K)] + ders[15] = get_dhdd_t_modelica(); // dH/drho at constant temperature [(J/kg) / (kg/m3)] + ders[16] = get_dhdd_p_modelica(); // dH/drho at constant pressure [(J/kg) / (kg/m3)] + ders[17] = get_dhdp_t_modelica(); // dH/dP at constant temperature [J/(kg-Pa)] + ders[18] = get_dhdp_d_modelica(); // dH/dP at constant density [J/(kg-Pa)] + ders[19] = get_dddh_p_num_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[20] = get_dddp_h_num_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + return 0; +} + +int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; + double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; + + if ((dd!=noValue)&&(dt!=noValue)) { + // call explicit functions in d and T + // get derivatives from Refprop library + if (debug) printf("Calling THERM2 with T=%f and rho=%f.\n",dt,dd); + THERM2lib (dt,dd,dxmol,spare5,spare6,spare9,spare10,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); + + // get derivatives of enthalpy + if (debug) printf("Calling DHD1 with T=%f and rho=%f.\n",dt,dd); + DHD1lib(dt,dd,dxmol,ddhdt_d,ddhdt_p,ddhdd_t,ddhdd_p,ddhdp_t,ddhdp_d); + + // get derivative of density with respect to enthalpy numerically + deltaP = 0.005; // 5 Pascal difference + pLow = dp - 0.5*deltaP; + pHigh = dp + 0.5*deltaP; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); + PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); + PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); + ddddp_h_num = (rhoHigh-rhoLow) / (pHigh-pLow); + + // get derivative of density with respect to enthalpy numerically + deltaH = 5.; // 5 Joule total difference + hLow = dh - 0.5*deltaH; + hHigh = dh + 0.5*deltaH; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); + PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); + PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); + ddddh_p_num = (rhoHigh-rhoLow) / (hHigh-hLow); + } else { // We have a problem! - printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); } + + switch(lerr){ + case 4: + sprintf(errormsg,"P=%f < 0",dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + default: + break; + } + return updateDers(ders, lerr); +} + +int updateTrns(double *trns, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + trns[0] = lerr;//error code + trns[1] = getETA_modelica(); // dynamic viscosity in Pa.s + trns[2] = getTCX_modelica(); // thermal conductivity in W/m.K return 0; } +int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + if ((dd!=noValue)&&(dt!=noValue)) { + // call explicit functions in d and T + // compute transport properties + if (debug) printf("Getting transport properties from T=%f and rho=%f.\n",dt,dd); + TRNPRPlib(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); + if (debug) printf("Thermal conductivity is lambda=%f W/m.K.\n",dtcx); + if (debug) printf("Dynamic viscosity is eta=%fµPa.s.\n",deta); + + } else { // We have a problem! + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); + } + + switch(lerr){ + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + default: + break; + } + return updateTrns(trns, lerr); +} + + int updateProps(double *props, long lerr){ //ASSIGN VALUES TO RETURN ARRAY props[0] = lerr;//error code @@ -823,10 +1158,8 @@ int updateProps(double *props, long lerr){ props[11] = getCV_modelica(); props[12] = getCP_modelica(); props[13] = getW_modelica(); //speed of sound - props[14] = getDDHP_modelica(); //ddhp - props[15] = getDDPH_modelica(); //ddph - props[16] = getWML_modelica(); - props[17] = getWMV_modelica(); + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); double dxlkg[ncmax], dxvkg[ncmax]; @@ -835,13 +1168,13 @@ int updateProps(double *props, long lerr){ for (int dim=0; dim - #ifdef __cplusplus extern "C" { #endif // __cplusplus - double props_REFPROP(char* what, char* statevars, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; - double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; - // - //double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, char * Ref); - //double REFPROP(char Output,char Name1, double Prop1, char Name2, double Prop2, double* xkg, std::string Ref, std::string Path, char * herr, int DEBUGMODE); + double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; + double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; #ifdef __cplusplus } #endif // __cplusplus diff --git a/_wrapper/v0.6/src/refpropwrappertest.cpp b/_wrapper/v0.6/src/refpropwrappertest.cpp index 218ce37..35970b1 100644 --- a/_wrapper/v0.6/src/refpropwrappertest.cpp +++ b/_wrapper/v0.6/src/refpropwrappertest.cpp @@ -14,6 +14,8 @@ int main(int argc, char* argv[]){ char errormsg[255+1024]; double* x; double *props; + double *ders; + double *trns; double sumx; int i; int nX = argc-5; @@ -26,7 +28,9 @@ int main(int argc, char* argv[]){ } x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(18+2*nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); sumx = 0; @@ -45,7 +49,7 @@ int main(int argc, char* argv[]){ //d = density(p, t); // props_REFPROP("", "pT" , "isobutan|propane", props, 1e5 , 293.0 , x, 0, "d:\\Programme\\REFPROP\\", errormsg, DEBUGMODE); // props_REFPROP ("", argv[1], argv[2] , props, atof(argv[3]), atof(argv[4]), x, 0, argv[5] , errormsg, DEBUG); - props_REFPROP ("", argv[1], argv[2] , props, atof(argv[3]), atof(argv[4]), x, 0, argv[5] , errormsg, DEBUG); + props_REFPROP ("", argv[1], argv[2] , ders, trns, props, atof(argv[3]), atof(argv[4]), x, 0, argv[5] , errormsg, DEBUG); // props_REFPROP("", "pT" , "isobutan|propane", props, 1e5 , 293.0 , x, 0, "/opt/refprop/", errormsg, DEBUG); printf("Errormessage: %s\n",errormsg); //printf("%c,%c,D %10.4f,%10.4f,%10.4f \n",argv[1][0],argv[1][1],atof(argv[3]),atof(argv[4]),props[5]); @@ -60,31 +64,47 @@ int main(int argc, char* argv[]){ props[8] = e; //inner energy*/ printf("h=%f J/kg\n",props[9]); //specific enthalpy printf("MM=%f kg/mol\n",props[3]); //molar weight + printf("s=%f J/kg\n",props[10]); //specific enthalpy + printf("a=%f J/kg\n",ders[2]); //helmholtz energy + printf("f=%f J/kg\n",ders[3]); //gibbs energy + printf("dhdd_T=%f J/kg m3/kg\n",ders[15]); //dhdd_T + printf("dhdd_p=%f J/kg m3/kg\n",ders[16]); //dhdd_p + printf("eta=%f Pa.s \n",trns[1]); // + printf("lambda=%f W/m.K\n",trns[2]); // + printf("dddh_p=%f \n",ders[19]); // + printf("dddp_h=%f \n\n",ders[20]); // + /*props[10] = s;//specific entropy props[11] = cv; props[12] = cp; props[13] = w; //speed of sound props[14] = wmliq; props[15] = wmvap;*/ - for (int ii=0;ii Date: Sun, 3 Mar 2013 18:08:09 +0100 Subject: [PATCH 21/57] Added if-clause for derivative calculations. Use PentaneTester.mo to see differences in numerical derivatives... --- Examples.mo | 20 +++++ Interfaces/PartialMixtureTwoPhaseMedium.mo | 3 +- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 47 +++++++++++ Media/Water.mo | 5 ++ Media/package.order | 1 + Testers/PentaneTester.mo | 91 +++++++-------------- _wrapper/v0.6/bin/librefprop_wrapper.so | Bin 306063 -> 306275 bytes _wrapper/v0.6/src/refprop_wrapper.cpp | 91 ++++++++++++--------- package.order | 1 + 9 files changed, 161 insertions(+), 98 deletions(-) create mode 100644 Examples.mo create mode 100644 Media/Water.mo diff --git a/Examples.mo b/Examples.mo new file mode 100644 index 0000000..736222f --- /dev/null +++ b/Examples.mo @@ -0,0 +1,20 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" + +extends Modelica.Icons.ExamplesPackage; + + + + + + + + + + + + +annotation(preferedView="info", + __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", + "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); +end Examples; diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index 5132d7d..08eea80 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Interfaces; partial package PartialMixtureTwoPhaseMedium "Template class for two phase medium of a mixture of substances " - extends Modelica.Media.Interfaces.PartialMixtureMedium; + extends Modelica.Media.Interfaces.PartialMixtureMedium(ThermoStates=inputChoice); constant Boolean smoothModel = false "true if the (derived) model should not generate state events"; constant Boolean onePhase = false @@ -30,6 +30,7 @@ partial package PartialMixtureTwoPhaseMedium constant InputChoice inputChoice=MixtureInputChoice.phX "Default choice of input variables for property computations"; + type FixedPhase = Integer(min=0,max=2) "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; record FluidLimits "validity limits for fluid model" diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 710d0e9..2286fc7 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -943,6 +943,53 @@ end ThermodynamicState; phase))); end density_TsX; + // explicit derivative functions for finite element models + redeclare function density_derp_h + "Return density derivative w.r.t. pressure at const specific enthalpy" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByPressure ddph "Density derivative w.r.t. pressure"; + algorithm + ddph := state.drhodp_h; + end density_derp_h; + + redeclare function density_derh_p + "Return density derivative w.r.t. specific enthalpy at constant pressure" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByEnthalpy ddhp + "Density derivative w.r.t. specific enthalpy"; + algorithm + ddhp := state.drhodh_p; + end density_derh_p; + + redeclare function density_derp_T + "Return density derivative w.r.t. pressure at const temperature" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByPressure ddpT "Density derivative w.r.t. pressure"; + algorithm + ddpT := state.drhodp_T; + end density_derp_T; + + redeclare function density_derT_p + "Return density derivative w.r.t. temperature at constant pressure" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DerDensityByTemperature ddTp "Density derivative w.r.t. temperature"; + algorithm + ddTp := state.drhodT_p; + end density_derT_p; + +// redeclare function density_derX +// "Return density derivative w.r.t. mass fraction" +// extends Modelica.Icons.Function; +// input ThermodynamicState state "thermodynamic state record"; +// output Density[nX] dddX "Derivative of density w.r.t. mass fraction"; +// algorithm +// dddX := +// end density_derX; + function pressure_dsX "calls REFPROP-Wrapper, returns pressure" extends Modelica.Icons.Function; input Modelica.SIunits.Density d; diff --git a/Media/Water.mo b/Media/Water.mo new file mode 100644 index 0000000..67db3b5 --- /dev/null +++ b/Media/Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"water"}); +end Water; diff --git a/Media/package.order b/Media/package.order index ca12c9b..400476d 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,2 +1,3 @@ Pentane R410mix +Water diff --git a/Testers/PentaneTester.mo b/Testers/PentaneTester.mo index 5d59117..cc8cce6 100644 --- a/Testers/PentaneTester.mo +++ b/Testers/PentaneTester.mo @@ -1,28 +1,9 @@ within REFPROP2Modelica.Testers; model PentaneTester "Evaporation of pentane at 1 bar" -package Medium = REFPROP2Modelica.Media.Pentane (debugmode=true); -// ",final explicitVars = "pd""; -//package Medium = REFPROP2Modelica.REFPROPMedium(final substanceNames={"CO2","water"}); - Medium.BaseProperties props(h(start=300e3),d(start=1)); -// Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); -/* Modelica.SIunits.SpecificEnthalpy h=Medium.specificEnthalpy_pTX(1e5,293,{.5,.5}); - Modelica.SIunits.Density d; - Modelica.SIunits.SpecificEntropy s; - Modelica.SIunits.Temperature Tsat; - Modelica.SIunits.Pressure psat; - */ -//Modelica.SIunits.Pressure p=Medium.pressure(props.state); -// Modelica.SIunits.MolarMass MM; -/*Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); - -Modelica.SIunits.DynamicViscosity eta_l = Medium.dynamicViscosity_liq(props.state); -Modelica.SIunits.DynamicViscosity eta_g = Medium.dynamicViscosity_gas(props.state); -*/ -// Real q = Medium.vapourQuality(props.state); -// Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); -// Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); -Real drhodtime_num; -Real drhodtime_ana; + package Medium = REFPROP2Modelica.Media.Pentane (debugmode=true); + Medium.BaseProperties props(h(start=300e3), d(start=1)); + Real drhodtime_num; + Real drhodtime_ana; Real factor1; Real factor2; Real check1; @@ -30,57 +11,47 @@ Real drhodtime_ana; Real deltap; Real deltah; Real ddddp_num; - Real ddddp_num_RP; + Real ddddp_RP; Real ddddp_ana; Real ddddh_num; - Real ddddh_num_RP; + Real ddddh_RP; Real ddddh_ana; equation deltap = 5; deltah = 5; props.p = 10e5;//1e5+3*time*4e5*(sin(20*time)+1)*0.5; - props.h = -3e5+time*7e5; + props.h = -3e5 + time*7e5; // get derivatives for checking factor1 = der(props.p); factor2 = der(props.h); - drhodtime_num = ddddp_num * factor1 + ddddh_num * factor2; - ddddp_num = (Medium.density_phX(props.p+0.5*deltap,props.h,props.X)-Medium.density_phX(props.p-0.5*deltap,props.h,props.X)) / deltap; - ddddh_num = (Medium.density_phX(props.p,props.h+0.5*deltah,props.X)-Medium.density_phX(props.p,props.h-0.5*deltah,props.X)) / deltah; + drhodtime_num = ddddp_num*factor1 + ddddh_num*factor2; + ddddp_num = (Medium.density_phX( + props.p + 0.5*deltap, + props.h, + props.X) - Medium.density_phX( + props.p - 0.5*deltap, + props.h, + props.X))/deltap; + ddddh_num = (Medium.density_phX( + props.p, + props.h + 0.5*deltah, + props.X) - Medium.density_phX( + props.p, + props.h - 0.5*deltah, + props.X))/deltah; - drhodtime_ana = ddddp_ana * factor1 + ddddh_ana * factor2; - -1 = ddddp_ana * 1/(props.state.dhdp_rho) * props.state.dhdrho_p; - ddddh_ana * props.state.dhdrho_p= 1; + drhodtime_ana = ddddp_ana*factor1 + ddddh_ana*factor2; + -1 = ddddp_ana*1/(props.state.dhdp_rho)*props.state.dhdrho_p; + ddddh_ana*props.state.dhdrho_p = 1; - check1 = ddddp_num - props.state.drhodp_h; - check2 = ddddh_num - props.state.drhodh_p; + check1 = abs(ddddp_num - props.state.drhodp_h)/abs(ddddp_num)*100 + "difference of derivatives in percent"; + check2 = abs(ddddh_num - props.state.drhodh_p)/abs(ddddh_num)*100 + "difference of derivatives in percent"; - ddddh_num_RP = props.state.drhodh_p "drho/dh at constant pressure"; - ddddp_num_RP = props.state.drhodp_h "drho/dp at constant enthalpy"; + ddddh_RP = props.state.drhodh_p "drho/dh at constant pressure"; + ddddp_RP = props.state.drhodp_h "drho/dp at constant enthalpy"; - // props.s = 5.88105; -// props.T = 400; -// props.state.x = 0.5; -// props.Xi = {.5}; -// props.X = {.1,.9}; -// props.Xi = {.5}; - // d = props.d; - //h = props.h; - //h = Medium.dewEnthalpy(props.sat); - //d = Medium.density(props.state); - //s = specificEntropy(props.state); - //s = props.state.s; -// MM = Medium.molarMass(props.state); -/* - Tsat = Medium.saturationTemperature(props.p,props.X); -// Tsat = Medium.temperature_pqX(props.p,0.5,props.X); - psat = Medium.saturationPressure(props.T,props.X); -// psat = Medium.pressure_TqX(props.T,0.5,props.X); -// h = Medium.dewEnthalpy(props.sat); -// s = Medium.dewEntropy(props.sat); - s = Medium.bubbleEntropy(props.sat); -// d = Medium.dewDensity(props.sat); - d = Medium.bubbleDensity(props.sat); -*/ end PentaneTester; diff --git a/_wrapper/v0.6/bin/librefprop_wrapper.so b/_wrapper/v0.6/bin/librefprop_wrapper.so index 414a73ae4c294134877bbfacde24368a9c2d0add..06fd285e35bce0a89ff33beafba307c755b3a3a1 100644 GIT binary patch literal 306275 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


%76N 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 BBq;y@ diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp index a4d7888..f6babfa 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ b/_wrapper/v0.6/src/refprop_wrapper.cpp @@ -171,7 +171,7 @@ double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; -double ddddp_h_num, ddddh_p_num; // get numerical derivatives +double ddddp_h, ddddh_p; int flushProperties(){ dt=noValue; @@ -217,8 +217,8 @@ int flushProperties(){ ddhdp_t=noValue; ddhdp_d=noValue; - ddddp_h_num=noValue; - ddddh_p_num=noValue; + ddddp_h=noValue; + ddddh_p=noValue; if (debug) printf ("Finished flushing normal fluid properties.\n"); return flushSaturation(); @@ -397,7 +397,7 @@ int loadLibrary(std::string pathToRefprop, char* error) { if (debug) printf ("Library instance successfully loaded.\n"); } else { // library was already loaded - if (debug) printf ("Library instance already, not doing anything.\n"); + if (debug) printf ("Library instance already loaded, not doing anything.\n"); } return 0; } @@ -772,12 +772,12 @@ double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] // Numerical derivatives // Derivative of density with respect to enthalpy at constant pressure -double get_dddh_p_num_modelica(){ - return ddddh_p_num*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J +double get_dddh_p_modelica(){ + return ddddh_p*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J } // Derivative of density with respect to pressure at constant enthalpy -double get_dddp_h_num_modelica(){ - return ddddp_h_num*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +double get_dddp_h_modelica(){ + return ddddp_h*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) } @@ -992,8 +992,8 @@ int updateDers(double *ders, long lerr){ ders[16] = get_dhdd_p_modelica(); // dH/drho at constant pressure [(J/kg) / (kg/m3)] ders[17] = get_dhdp_t_modelica(); // dH/dP at constant temperature [J/(kg-Pa)] ders[18] = get_dhdp_d_modelica(); // dH/dP at constant density [J/(kg-Pa)] - ders[19] = get_dddh_p_num_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] - ders[20] = get_dddp_h_num_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + ders[19] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] return 0; } @@ -1015,33 +1015,50 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ if (debug) printf("Calling DHD1 with T=%f and rho=%f.\n",dt,dd); DHD1lib(dt,dd,dxmol,ddhdt_d,ddhdt_p,ddhdd_t,ddhdd_p,ddhdp_t,ddhdp_d); - // get derivative of density with respect to enthalpy numerically - deltaP = 0.005; // 5 Pascal difference - pLow = dp - 0.5*deltaP; - pHigh = dp + 0.5*deltaP; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); - PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); - PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); - ddddp_h_num = (rhoHigh-rhoLow) / (pHigh-pLow); - - // get derivative of density with respect to enthalpy numerically - deltaH = 5.; // 5 Joule total difference - hLow = dh - 0.5*deltaH; - hHigh = dh + 0.5*deltaH; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); - PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); - PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); - ddddh_p_num = (rhoHigh-rhoLow) / (hHigh-hLow); + /* + * With the above values, the cyclic relation can be used to + * determine all necessary values. + * + * -1 = ddddp_ana * 1/(props.state.dhdp_rho) * props.state.dhdrho_p; + * ddddh_ana * props.state.dhdrho_p= 1; + * + * Below is a numerical approximation due to problems in the + * two-phase region. + */ + + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + ddddp_h = -1. * ddhdp_d / ddhdd_p; + ddddh_p = 1./ddhdd_p; + } else { // two-phase region, get derivative of density with respect to enthalpy numerically + if (debug) printf ("Using two-phase derivatives.\n"); + deltaP = 0.00005; // 0.05 Pascal difference + pLow = dp - 0.5*deltaP; + pHigh = dp + 0.5*deltaP; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); + PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); + PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); + ddddp_h = (rhoHigh-rhoLow) / (pHigh-pLow); + + // get derivative of density with respect to enthalpy numerically + deltaH = 0.05; // 0.05 Joule total difference + hLow = dh - 0.5*deltaH; + hHigh = dh + 0.5*deltaH; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); + PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); + PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); + ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + } } else { // We have a problem! printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); diff --git a/package.order b/package.order index 0a82484..9f103ad 100644 --- a/package.order +++ b/package.order @@ -1,4 +1,5 @@ REFPROP_PATH +Examples Media Testers Interfaces From 97f7f19fc2573e02a01c3df4532ec915853f2a8e Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 6 Mar 2013 19:00:27 +0100 Subject: [PATCH 22/57] Update refprop_wrapper.cpp --- _wrapper/v0.6/src/refprop_wrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp index f6babfa..4748ee3 100644 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ b/_wrapper/v0.6/src/refprop_wrapper.cpp @@ -28,7 +28,7 @@ #include #include // tolower, toupper, etc -#include +#include "refprop_lib.h" //#include //#include //#include From 0e0115151ecd02a8780f299500ee0ea2c794148e Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 6 Mar 2013 19:01:56 +0100 Subject: [PATCH 23/57] Update readme.md Included Henning's hint regarding the windows compiler console --- readme.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index b490793..4b9b7fe 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,3 @@ - #Welcome to REFPROP2Modelica! This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. @@ -11,7 +10,7 @@ If you only want to run the wrapper without compiling it from source, you can us > For Windows, please follow these instructions > > 1. After downloading and unzipping rename folder containing these files to `REFPROP2Modelica`. -> 2. Double click on `_wrapper\v0.6\Makefile.bat` +> 2. Run `_wrapper\v0.6\Makefile.bat` from your Visual Studio console. > 3. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; > @@ -41,4 +40,4 @@ If you are interested in this kind of software, you might also consider the foll 1. https://github.com/Heineken/REFPROP2Modelica (The original version of this library) 2. https://github.com/thorade/HelmholtzMedia (A Modelica implementation the Helmholtz functions) -3. http://coolprop.sourceforge.net/ (A free fluid property library also based on Helmholtz formulation) \ No newline at end of file +3. http://coolprop.sourceforge.net/ (A free fluid property library also based on Helmholtz formulation) From f785cb3fadbf6c94993b148c84217276283c3975 Mon Sep 17 00:00:00 2001 From: jowr Date: Mon, 22 Jul 2013 15:53:43 +0200 Subject: [PATCH 24/57] Update readme.md Updated some instructions for Windows. --- readme.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 4b9b7fe..f39d94a 100644 --- a/readme.md +++ b/readme.md @@ -2,10 +2,12 @@ This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. ## Installation Instructions -If you only want to run the wrapper without compiling it from source, you can use the provided makefiles to install the precompiled static libraries. +If you only want to run the wrapper without compiling it from source, you can use the provided makefiles to +install the precompiled static libraries. ### Windows -**Since I do not run Windows myself, I am not able to try this myself. Could you, dear Windows users, please provide me with feedback and the actual `.lib` files needed for the instructions below to work.** +**Since I do not run Windows myself, I am not able to try this myself. Could you, dear Windows users, please +provide me with feedback and the actual `.lib` files needed for the instructions below to work.** > For Windows, please follow these instructions > @@ -23,14 +25,20 @@ For installing on a Linux machine, please follow these instructions 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; ## Compiling +Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile the wrapper files +yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it +via your package manager with `sudo apt-get install libpoco-dev`. Follow the instructions in +http://www.appinf.com/download/QuickStartGuide.pdf if you experience problems with Poco. The general +idea is to use this framework to implement platform independent library loading and caching, but it is still +a long way to go. ### Windows -Please feel free to contribute to this part of the work. I was told that the code works with VisualStudio and VisualStudio Express, but I cannot provide instructions or feedback. +Please feel free to contribute to this part of the work. I was told that the code works with VisualStudio and VisualStudio Express, but I cannot provide instructions or feedback. +Executing the commands `cl /c /EHsc "refprop_wrapper.cpp"` and `lib "refprop_wrapper.obj"` in the `src` directory should create the `.lib` for you. ### Linux For compiling on a Linux machine, please follow the instructions in the Makefile provided in the directory of the wrapper sources. You might have to adjust some directorie names and install all the compilers and libraries required. - -Afterwards, you can go to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. This compiles and installs a dynamic library on your system. To remove the files from your system, please use `sudo make uninstall`. Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile future versions of the wrapper files yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it via your package manager with `sudo apt-get install libpoco-dev` .The general idea is to use this framework to implement platform independent library loading and caching, but it is still a long way to go. +Afterwards, you can go to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. This compiles and installs a dynamic library on your system. To remove the files from your system, please use `sudo make uninstall`. ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. From 23d749e2e2230058949e007203912799c52134fc Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 24 Jul 2013 18:18:35 +0200 Subject: [PATCH 25/57] Update readme.md Removed Poco dependency and added instructions for Windows users. --- readme.md | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/readme.md b/readme.md index f39d94a..1a27569 100644 --- a/readme.md +++ b/readme.md @@ -2,49 +2,35 @@ This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. ## Installation Instructions -If you only want to run the wrapper without compiling it from source, you can use the provided makefiles to -install the precompiled static libraries. +You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. ### Windows -**Since I do not run Windows myself, I am not able to try this myself. Could you, dear Windows users, please -provide me with feedback and the actual `.lib` files needed for the instructions below to work.** +Since I do not run Windows regularly, I am not able to test many things myself. Could you, dear Windows users, please +provide me with feedback? + +1. After downloading and unzipping, rename folder to `REFPROP2Modelica`. +2. Run `_wrapper\v0.7\Makefile.bat` from your Visual Studio console, tested with VS9.0 (2008). +3. Make sure to have the shared library `refprop.dll` available on your system. +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; -> For Windows, please follow these instructions -> -> 1. After downloading and unzipping rename folder containing these files to `REFPROP2Modelica`. -> 2. Run `_wrapper\v0.6\Makefile.bat` from your Visual Studio console. -> 3. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; -> ### Linux For installing on a Linux machine, please follow these instructions -1. After downloading and unzipping rename folder containing these files to `REFPROP2Modelica`. -2. Open a command prompt in `_wrapper/v0.6/` and run `sudo make install_static`. -3. Make sure to have the shared library `librefprop.so` available in the same directory as the `fluids` folder. You might want to check https://github.com/jowr/librefprop.so for details. +1. After downloading and unzipping, rename folder to `REFPROP2Modelica`. +2. Open a command prompt in `_wrapper/v0.7/`, then run `make all` and `sudo make install_static`. +3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; +5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. +6. ... and finally to remove the files from your system, please use `sudo make uninstall`. -## Compiling -Please be aware that you need a copy of the Poco C++ framework v1.3.6 or newer to compile the wrapper files -yourself. You can find it at: http://pocoproject.org/ and https://github.com/pocoproject/poco or install it -via your package manager with `sudo apt-get install libpoco-dev`. Follow the instructions in -http://www.appinf.com/download/QuickStartGuide.pdf if you experience problems with Poco. The general -idea is to use this framework to implement platform independent library loading and caching, but it is still -a long way to go. - -### Windows -Please feel free to contribute to this part of the work. I was told that the code works with VisualStudio and VisualStudio Express, but I cannot provide instructions or feedback. -Executing the commands `cl /c /EHsc "refprop_wrapper.cpp"` and `lib "refprop_wrapper.obj"` in the `src` directory should create the `.lib` for you. - -### Linux -For compiling on a Linux machine, please follow the instructions in the Makefile provided in the directory of the wrapper sources. You might have to adjust some directorie names and install all the compilers and libraries required. -Afterwards, you can go to the directory `_wrapper/v0.6/` and call `make all` and `sudo make install` as well as `sudo make fixit` to compile and install the wrapper library. This compiles and installs a dynamic library on your system. To remove the files from your system, please use `sudo make uninstall`. ## General Remarks -Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop. +Please note that you need a working and licensed copy of Refprop in order to use the software provided here. +This is not a replacement for Refprop, only a wrapper to use it with Modelica. ## Links -If you are interested in this kind of software, you might also consider the following projects: +If you are interested in this kind of software, you might also want to consider the following projects: 1. https://github.com/Heineken/REFPROP2Modelica (The original version of this library) 2. https://github.com/thorade/HelmholtzMedia (A Modelica implementation the Helmholtz functions) From ac22aa0a062fed16d64c675ed3cf8bee2730449a Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 24 Jul 2013 19:19:04 +0200 Subject: [PATCH 26/57] done added dummy bin folder to avoid compile-time issues From d3183f3bd0a90f03d0c2e99f08bc1e8d0618b10a Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 24 Jul 2013 19:23:42 +0200 Subject: [PATCH 27/57] removed old folders --- _wrapper/v0.5/REFPROP_dll.H | 199 --- _wrapper/v0.5/REFPROP_wrapper.cpp | 797 --------- _wrapper/v0.5/REFPROP_wrapper.lib | Bin 39942 -> 0 bytes _wrapper/v0.5/makefile.bat | 4 - _wrapper/v0.5/refprop_wrapper.h | 42 - _wrapper/v0.5/refprop_wrapper_linux.cpp | 1252 --------------- _wrapper/v0.5/refpropwrappertest.cpp | 70 - _wrapper/v0.6/Makefile | 169 -- _wrapper/v0.6/Makefile.bat | 25 - _wrapper/v0.6/bin/librefprop_wrapper.so | Bin 306275 -> 0 bytes _wrapper/v0.6/src/refprop_lib.h | 674 -------- _wrapper/v0.6/src/refprop_wrapper.cpp | 1870 ---------------------- _wrapper/v0.6/src/refprop_wrapper.h | 32 - _wrapper/v0.6/src/refpropwrappertest.cpp | 160 -- 14 files changed, 5294 deletions(-) delete mode 100644 _wrapper/v0.5/REFPROP_dll.H delete mode 100644 _wrapper/v0.5/REFPROP_wrapper.cpp delete mode 100644 _wrapper/v0.5/REFPROP_wrapper.lib delete mode 100644 _wrapper/v0.5/makefile.bat delete mode 100644 _wrapper/v0.5/refprop_wrapper.h delete mode 100644 _wrapper/v0.5/refprop_wrapper_linux.cpp delete mode 100644 _wrapper/v0.5/refpropwrappertest.cpp delete mode 100644 _wrapper/v0.6/Makefile delete mode 100644 _wrapper/v0.6/Makefile.bat delete mode 100644 _wrapper/v0.6/bin/librefprop_wrapper.so delete mode 100644 _wrapper/v0.6/src/refprop_lib.h delete mode 100644 _wrapper/v0.6/src/refprop_wrapper.cpp delete mode 100644 _wrapper/v0.6/src/refprop_wrapper.h delete mode 100644 _wrapper/v0.6/src/refpropwrappertest.cpp diff --git a/_wrapper/v0.5/REFPROP_dll.H b/_wrapper/v0.5/REFPROP_dll.H deleted file mode 100644 index 080a91c..0000000 --- a/_wrapper/v0.5/REFPROP_dll.H +++ /dev/null @@ -1,199 +0,0 @@ -// Definitions of the Refprop types -typedef void (__stdcall *fp_ABFL1dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_ABFL2dllTYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_ACTVYdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_AGdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_CCRITdllTYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CP0dllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_CRITPdllTYPE)(double *,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CSATKdllTYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CV2PKdllTYPE)(long &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_CVCPKdllTYPE)(long &,double &,double &,double &,double &); -typedef void (__stdcall *fp_CVCPdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_DBDTdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_DBFL1dllTYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DBFL2dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_DDDPdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DDDTdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DEFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DHD1dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_DHFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DHFL2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DHFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DIELECdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DOTFILLdllTYPE)(long &,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DPDD2dllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPDDKdllTYPE)(long &,double &,double &,double &); -typedef void (__stdcall *fp_DPDDdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPDTKdllTYPE)(long &,double &,double &,double &); -typedef void (__stdcall *fp_DPDTdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_DPTSATKdllTYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_DSFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_DSFL2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_ENTHALdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_ENTROdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_ESFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_FGCTYdllTYPE)(double &,double &,double *,double *); -typedef void (__stdcall *fp_FPVdllTYPE)(double &,double &,double &,double *,double &); -typedef void (__stdcall *fp_GERG04dllTYPE)(long &,long &,long &,char*,long ); -typedef void (__stdcall *fp_GETFIJdllTYPE)(char*,double *,char*,char*,long ,long ,long ); -typedef void (__stdcall *fp_GETKTVdllTYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); -typedef void (__stdcall *fp_GIBBSdllTYPE)(double &,double &,double *,double &,double &); -typedef void (__stdcall *fp_HSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_INFOdllTYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_LIMITKdllTYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_LIMITSdllTYPE)(char*,double *,double &,double &,double &,double &,long ); -typedef void (__stdcall *fp_LIMITXdllTYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_MELTPdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_MELTTdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_MLTH2OdllTYPE)(double &,double &,double &); -typedef void (__stdcall *fp_NAMEdllTYPE)(long &,char*,char*,char*,long ,long ,long ); -typedef void (__stdcall *fp_PDFL1dllTYPE)(double &,double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_PDFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PEFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PHFL1dllTYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PHFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PQFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PREOSdllTYPE)(long &); -typedef void (__stdcall *fp_PRESSdllTYPE)(double &,double &,double *,double &); -typedef void (__stdcall *fp_PSFL1dllTYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PSFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_PUREFLDdllTYPE)(long &); -typedef void (__stdcall *fp_QMASSdllTYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_QMOLEdllTYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATDdllTYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SATEdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATHdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATPdllTYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SATSdllTYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_SATTdllTYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); -typedef void (__stdcall *fp_SETAGAdllTYPE)(long &,char*,long ); -typedef void (__stdcall *fp_SETKTVdllTYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); -typedef void (__stdcall *fp_SETMIXdllTYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); -typedef void (__stdcall *fp_SETMODdllTYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); -typedef void (__stdcall *fp_SETREFdllTYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); -typedef void (__stdcall *fp_SETUPdllTYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); -typedef void (__stdcall *fp_SPECGRdllTYPE)(double &,double &,double &,double &); -typedef void (__stdcall *fp_SUBLPdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SUBLTdllTYPE)(double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SURFTdllTYPE)(double &,double &,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_SURTENdllTYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); -typedef void (__stdcall *fp_TDFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TEFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_THERM0dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERM2dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERM3dllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THERMdllTYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); -typedef void (__stdcall *fp_THFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TPFLSHdllTYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TPFL2dllTYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long );//added by Henning Francke -typedef void (__stdcall *fp_TPRHOdllTYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TQFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TRNPRPdllTYPE)(double &,double &,double *,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_TSFLSHdllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); -typedef void (__stdcall *fp_VIRBdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_VIRCdllTYPE)(double &,double *,double &); -typedef void (__stdcall *fp_WMOLdllTYPE)(double *,double &); -typedef void (__stdcall *fp_XMASSdllTYPE)(double *,double *,double &); -typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double &); - -//Define explicit function pointers -fp_ABFL1dllTYPE ABFL1dll; -fp_ABFL2dllTYPE ABFL2dll; -fp_ACTVYdllTYPE ACTVYdll; -fp_AGdllTYPE AGdll; -fp_CCRITdllTYPE CCRITdll; -fp_CP0dllTYPE CP0dll; -fp_CRITPdllTYPE CRITPdll; -fp_CSATKdllTYPE CSATKdll; -fp_CV2PKdllTYPE CV2PKdll; -fp_CVCPKdllTYPE CVCPKdll; -fp_CVCPdllTYPE CVCPdll; -fp_DBDTdllTYPE DBDTdll; -fp_DBFL1dllTYPE DBFL1dll; -fp_DBFL2dllTYPE DBFL2dll; -fp_DDDPdllTYPE DDDPdll; -fp_DDDTdllTYPE DDDTdll; -fp_DEFLSHdllTYPE DEFLSHdll; -fp_DHD1dllTYPE DHD1dll; -fp_DHFLSHdllTYPE DHFLSHdll; -fp_DHFL1dllTYPE DHFL1dll; //added by Henning Francke -fp_DHFL2dllTYPE DHFL2dll; //added by Henning Francke -fp_DIELECdllTYPE DIELECdll; -fp_DOTFILLdllTYPE DOTFILLdll; -fp_DPDD2dllTYPE DPDD2dll; -fp_DPDDKdllTYPE DPDDKdll; -fp_DPDDdllTYPE DPDDdll; -fp_DPDTKdllTYPE DPDTKdll; -fp_DPDTdllTYPE DPDTdll; -fp_DPTSATKdllTYPE DPTSATKdll; -fp_DSFLSHdllTYPE DSFLSHdll; -fp_DSFL1dllTYPE DSFL1dll; //added by Henning Francke -fp_DSFL2dllTYPE DSFL2dll; //added by Henning Francke -fp_ENTHALdllTYPE ENTHALdll; -fp_ENTROdllTYPE ENTROdll; -fp_ESFLSHdllTYPE ESFLSHdll; -fp_FGCTYdllTYPE FGCTYdll; -fp_FPVdllTYPE FPVdll; -fp_GERG04dllTYPE GERG04dll; -fp_GETFIJdllTYPE GETFIJdll; -fp_GETKTVdllTYPE GETKTVdll; -fp_GIBBSdllTYPE GIBBSdll; -fp_HSFLSHdllTYPE HSFLSHdll; -fp_INFOdllTYPE INFOdll; -fp_LIMITKdllTYPE LIMITKdll; -fp_LIMITSdllTYPE LIMITSdll; -fp_LIMITXdllTYPE LIMITXdll; -fp_MELTPdllTYPE MELTPdll; -fp_MELTTdllTYPE MELTTdll; -fp_MLTH2OdllTYPE MLTH2Odll; -fp_NAMEdllTYPE NAMEdll; -fp_PDFL1dllTYPE PDFL1dll; -fp_PDFLSHdllTYPE PDFLSHdll; -fp_PEFLSHdllTYPE PEFLSHdll; -fp_PHFL1dllTYPE PHFL1dll; -fp_PHFLSHdllTYPE PHFLSHdll; -fp_PQFLSHdllTYPE PQFLSHdll; -fp_PREOSdllTYPE PREOSdll; -fp_PRESSdllTYPE PRESSdll; -fp_PSFL1dllTYPE PSFL1dll; -fp_PSFLSHdllTYPE PSFLSHdll; -fp_PUREFLDdllTYPE PUREFLDdll; -fp_QMASSdllTYPE QMASSdll; -fp_QMOLEdllTYPE QMOLEdll; -fp_SATDdllTYPE SATDdll; -fp_SATEdllTYPE SATEdll; -fp_SATHdllTYPE SATHdll; -fp_SATPdllTYPE SATPdll; -fp_SATSdllTYPE SATSdll; -fp_SATTdllTYPE SATTdll; -fp_SETAGAdllTYPE SETAGAdll; -fp_SETKTVdllTYPE SETKTVdll; -fp_SETMIXdllTYPE SETMIXdll; -fp_SETMODdllTYPE SETMODdll; -fp_SETREFdllTYPE SETREFdll; -fp_SETUPdllTYPE SETUPdll; -fp_SPECGRdllTYPE SPECGRdll; -fp_SUBLPdllTYPE SUBLPdll; -fp_SUBLTdllTYPE SUBLTdll; -fp_SURFTdllTYPE SURFTdll; -fp_SURTENdllTYPE SURTENdll; -fp_TDFLSHdllTYPE TDFLSHdll; -fp_TEFLSHdllTYPE TEFLSHdll; -fp_THERM0dllTYPE THERM0dll; -fp_THERM2dllTYPE THERM2dll; -fp_THERM3dllTYPE THERM3dll; -fp_THERMdllTYPE THERMdll; -fp_THFLSHdllTYPE THFLSHdll; -fp_TPFLSHdllTYPE TPFLSHdll; -fp_TPFL2dllTYPE TPFL2dll;//added by Henning Francke -fp_TPRHOdllTYPE TPRHOdll; -fp_TQFLSHdllTYPE TQFLSHdll; -fp_TRNPRPdllTYPE TRNPRPdll; -fp_TSFLSHdllTYPE TSFLSHdll; -fp_VIRBdllTYPE VIRBdll; -fp_VIRCdllTYPE VIRCdll; -fp_WMOLdllTYPE WMOLdll; -fp_XMASSdllTYPE XMASSdll; -fp_XMOLEdllTYPE XMOLEdll; diff --git a/_wrapper/v0.5/REFPROP_wrapper.cpp b/_wrapper/v0.5/REFPROP_wrapper.cpp deleted file mode 100644 index 22897e8..0000000 --- a/_wrapper/v0.5/REFPROP_wrapper.cpp +++ /dev/null @@ -1,797 +0,0 @@ -/* - wrapper code for a static library containing functions from the dynamic library refprop.dll - to be used from Modelica - - This file is released under the Modelica License 2. - - Coded in 2010 by - Henning Francke - francke@gfz-potsdam.de - - Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences - Telegrafenberg, D-14473 Potsdam - - needs - REFPROP_dll.H - header for REFPROP.DLL slightly modified from %REFPROPDIR%\Examples\CPP.ZIP - refprop_wrapper.h - header for static REFPROP_wrapper.lib, also needed by Dymola - - compile with Visual C++ Compiler: - cl /c REFPROP_wrapper.cpp - lib REFPROP_wrapper.obj - copy REFPROP_wrapper.lib "%DYMOLADIR%\bin\lib\" - copy refprop_wrapper.h "%DYMOLADIR%\Source\" -*/ -//#define DEBUGMODE 1 - -#include -#include -#include "REFPROP_wrapper.h" -#include "REFPROP_dll.h" - - -// Some constants... -const long filepathlength=1024; -const long errormessagelength=255+filepathlength; -const long lengthofreference=3; -const long refpropcharlength=255; -const long ncmax=20; // Note: ncmax is the max number of components - -char *str_replace(char *str, char *search, char *replace, long *count) { - int i,n_ret; - int newlen = strlen(replace); - int oldlen = strlen(search); - char *ret; - *count = 0; - - //count occurrences of searchstring - for (i = 0; oldlen && str[i]; ++i) - if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr - ++*count, i+=oldlen - 1; - } - ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); - if (!ret){ - printf("Could not allocate memory"); - return ""; - } - - if (!*count){ - strncpy(ret,str,n_ret); - //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); - }else{ - i = 0; - while (*str) - if (strstr(str, search) == str) - strncpy(&ret[i], replace,n_ret-i-1), - i += newlen, - str += oldlen; - else - ret[i++] = *str++; - ret[i] = '\0'; - } - return ret; -} - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH, long* nX, char* herr, HINSTANCE* RefpropdllInstance, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP - char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - long ierr=0; - - if (strlen(REFPROP_PATH)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH too long (%i > %i)\n",strlen(REFPROP_PATH),filepathlength); - return 0; - } - - strcpy(FLD_PATH, REFPROP_PATH); - strcpy(DLL_PATH, REFPROP_PATH); - if (REFPROP_PATH[strlen(REFPROP_PATH)-1]=='\\'){ //if last char is backslash - strcat(DLL_PATH, "refprop.dll"); - strcat(FLD_PATH, "fluids\\"); - }else{//add missing backslash - strcat(DLL_PATH,"\\refprop.dll"); - strcat(FLD_PATH, "\\fluids\\"); - } - - *RefpropdllInstance = LoadLibrary(DLL_PATH); - if (!*RefpropdllInstance){ - sprintf(errormsg,"ERROR in opening REFPROP.DLL at \"%s\"",DLL_PATH); - return 100; - } - - - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; - //char hf[refpropcharlength*ncmax]; - char *hf; - - - //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".fld|"); - //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH,filepathlength-strlen(replace)); - - int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; - hf = (char*) calloc(hf_len, sizeof(char)); - - strncpy(hf,FLD_PATH,hf_len); - strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... - if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %i)\n",ncmax); - return 0; - } - strncat(hf,".fld",hf_len-strlen(hf)); - if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); - - strncpy(hfmix,FLD_PATH,filepathlength+1);//add absolute path - strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); - strcpy(hrf,"DEF"); - - - //...Call SETUP to initialize the program - SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(*RefpropdllInstance,"SETUPdll"); - //printf("hf:%s\n hrf: %s\n hfmix: %s\n",hf,hrf,hfmix); - - - if (DEBUGMODE) printf("Running SETUPdll...\n"); - SETUPdll(*nX, hf, hfmix, hrf, ierr, herr, - hf_len,filepathlength+1+7, - lengthofreference,errormessagelength); - if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); - - -// if (DEBUGMODE) printf("Error code processing...\n"); - switch(ierr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening file %s",hf); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - strncpy(errormsg,herr,errormessagelength); - break; - } - free(hf); - return ierr; -} - - -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevars: string of any combination of two variables out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message -*/ - char statevars[3]; - double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; - long nX,ierr=0; //zero means no error - char herr[errormessagelength+1]; - HINSTANCE RefpropdllInstance;// Then have windows load the library. - - if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); - - //initialize interface to REFPROP.dll - - if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ - printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); - return 0; - } - - //CALCULATE MOLAR MASS - WMOLdll = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); - WMOLdll(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - wm /= 1000; //g/mol -> kg/mol - - //identify and assign passed state variables - statevars[0] = tolower(statevars_in[0]); - statevars[1] = tolower(statevars_in[1]); - statevars[2] = '\0'; - if (statevars[0]!='\0'){ - if (statevars[0]==statevars[1]){ - props[0] = 3; - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); - return 0; - } - for (int ii=0;ii<2;ii++){ - val = (ii==0?statevar1:statevar2); - switch(statevars[ii]){ - case 'p': - p = val/1000; //Pa->kPa - break; - case 't': - T = val; - break; - case 's': - s = val*wm; //J/(kg·K) -> kJ/(mol·K) - break; - case 'h': - h = val*wm; //J/kg --> kJ/mol - break; - case 'd': - d = val/wm/1000; //kg/m³ -> mol/dm³ - break; - case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - q = val; - break; - default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ - return 0; - } - } - } - -/* -//...If phase j is known, call TPRHOdll: - long j=2; //phase definition(j=1: Liquid, j=2: Vapor) - long tmp_int=0; - TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHOdll(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); -*/ -//...If phase is not known, call TPFLSH - double xliq[ncmax],xvap[ncmax],f[ncmax]; - long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ -// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); - if (ierr==0){ - if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ -// strcat(errormsg,"Bin in TP!"); - if (phase==2){ //fluid state is known to be two phase - TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2dll(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - }else{ - TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSHdll(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); - PHFL1dll(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ - PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSHdll(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ - if (phase==1){ //fluid state is known to be single phase - PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1dll(p,d,x,T,ierr,herr,errormessagelength); - }else{ - PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSHdll(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1dll(p,s,x,kph,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ - PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSHdll(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ - PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSHdll(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1dll(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); - }else{*/ - THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSHdll (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ - TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSHdll(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ - TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); - long kr = 2; - TSFLSHdll (T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ - TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSHdll(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: - DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1dll(d,h,x,T,ierr,herr,errormessagelength); - break; - case 2: - DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2dll(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: - DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSHdll(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ - HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSHdll(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: - DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1dll(d,s,x,T,ierr,herr,errormessagelength); - break; - case 2: - DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2dll(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: - DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSHdll(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s", statevars); - } - - switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE - case 'v': //dynamic viscosity uPa.s - case 'l': //thermal conductivity W/m.K - TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRPdll (T,d,x,eta,tcx,ierr,herr,errormessagelength); - } - - - switch(ierr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 4: - sprintf(errormsg,"P=%f < 0",p); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",T,p); - break; - case 8: - strcpy(errormsg,"x out of range (component and/or sum < 0 or > 1)"); - break; - case 9: - sprintf(errormsg,"x or T=%f out of range",T); - break; - case 12: - sprintf(errormsg,"x out of range and P=%f < 0",p); - break; - case 13: - sprintf(errormsg,"x, T=%f and p=%f out of range",T,p); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",d); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",d); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm³ -> kg/m³ - dl *= wmliq*1000; //mol/dm³ -> kg/m³ - dv *= wmvap*1000; //mol/dm³ -> kg/m³ - e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol·K) -> J/(kg·K) - cv /= wm; - cp /= wm; - p *= 1000; //kPa->Pa - if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis - eta/=1e6; //uPa.s -> Pa.s - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e; //inner energy - props[9] = h; //specific enthalpy - props[10] = s;//specific entropy - props[11] = cv; - props[12] = cp; - props[13] = w; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii kg/mol - - - //identify and assign passed state variables - statevar[0] = tolower(statevar[0]); - if (statevar[0]!='\0'){ - switch(statevar[0]){ - case 'p': - p = statevarval/1000; //Pa->kPa - break; - case 't': - T = statevarval; - break; - case 'd': - d = statevarval/wm/1000; //kg/m³ -> mol/dm³ - break; -/* case 's': - s = statevarval*wm; //J/(kg·K) -> kJ/(mol·K) - break; - case 'h': - h = statevarval*wm; //J/kg --> kJ/mol - break; -*/ default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable: %c", statevarval); - return 0; - } - } - double xliq[ncmax],xvap[ncmax],f[ncmax]; - - long j=2,kr; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - if (ierr==0) - if (~strcmp(statevar,"t")){ - SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATTdll(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - }else if (~strcmp(statevar,"p")){ - SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATPdll(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - }else if (~strcmp(statevar,"d")){ - SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATDdll(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - - switch(ierr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 8: - strcpy(errormsg,"x out of range"); - break; - case 9: - strcpy(errormsg,"T and x out of range"); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - strncpy(errormsg,herr,errormessagelength); - } - - /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); - SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); - SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOLdll(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOLdll(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm³ -> kg/m³ - dl *= wmliq*1000; //mol/dm³ -> kg/m³ - dv *= wmvap*1000; //mol/dm³ -> kg/m³ -/* e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol·K) -> J/(kg·K) -*/ p *= 1000; //kPa->Pa - } - - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in kPa->Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int 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 -#if defined(WIN32) || defined(_WIN32) -# include -//# include "REFPROP_dll.h" -#else // assuming Linux system -# include -# include -//# include // dlopen etc -# include // tolower etc -#endif -#include -//# error "Could not determine system." -#include "refprop_wrapper.h" - -// get the POCO classes -#include "Poco/SharedLibrary.h" -#include "Poco/Path.h" -#include "Poco/File.h" -#include "Poco/Environment.h" -#include "Poco/StringTokenizer.h" -#include "Poco/String.h" -#include "Poco/Exception.h" - - -// Some constants... -const long maxstringlength=10000; -// const long filepathlength=1024; -// const long errormessagelength=255+filepathlength; -// const long lengthofreference=3; -// const long refpropcharlength=255; -// const long ncmax=20; // Note: ncmax is the max number of components - -Poco::SharedLibrary *RefpropdllInstance = NULL; -char loadedfluids[refpropcharlength]; -char loadedpath[filepathlength]; - -// Define the functions either by their pointers or type. -WMOLdll_POINTER WMOL = NULL; -TPFL2dll_POINTER TPFL2 = NULL; -TPFLSHdll_POINTER TPFLSH = NULL; -PHFL1dll_POINTER PHFL1 = NULL; -PHFLSHdll_POINTER PHFLSH = NULL; -PDFL1dll_POINTER PDFL1 = NULL; -PDFLSHdll_POINTER PDFLSH = NULL; -PSFLSHdll_POINTER PSFLSH = NULL; -PQFLSHdll_POINTER PQFLSH = NULL; -THFLSHdll_POINTER THFLSH = NULL; -TDFLSHdll_POINTER TDFLSH = NULL; -TSFLSHdll_POINTER TSFLSH = NULL; -TQFLSHdll_POINTER TQFLSH = NULL; -DHFL1dll_POINTER DHFL1 = NULL; -DHFL2dll_POINTER DHFL2 = NULL; -DHFLSHdll_POINTER DHFLSH = NULL; -HSFLSHdll_POINTER HSFLSH = NULL; -DSFL1dll_POINTER DSFL1 = NULL; -DSFL2dll_POINTER DSFL2 = NULL; -DSFLSHdll_POINTER DSFLSH = NULL; -TRNPRPdll_POINTER TRNPRP = NULL; -SATTdll_POINTER SATT = NULL; -SATPdll_POINTER SATP = NULL; -SATDdll_POINTER SATD = NULL; - -// char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { -// int i,n_ret; -// int newlen = strlen(replace); -// int oldlen = strlen(search); -// char *ret; -// *count = 0; -// -// //count occurrences of searchstring -// for (i = 0; oldlen && str[i]; ++i) -// if (strstr(&str[i], search) == &str[i]){ // if walk through is at searchstr -// ++*count, i+=oldlen - 1; -// } -// ret = (char *) calloc(n_ret = (strlen(str) + 1 + *count * (newlen - oldlen)), sizeof(char)); -// if (!ret){ -// printf("Could not allocate memory"); -// return ""; -// } -// -// if (!*count){ -// strncpy(ret,str,n_ret); -// //if (DEBUGMODE) printf("RET: %i %s\n",oldlen,str); -// }else{ -// i = 0; -// while (*str) -// if (strstr(str, search) == str) -// strncpy(&ret[i], replace,n_ret-i-1), -// i += newlen, -// str += oldlen; -// else -// ret[i++] = *str++; -// ret[i] = '\0'; -// } -// return ret; -// } - -//str_replace (fluidnames, "|", replace, nX) -char *str_replace(char *str, char *search, char *replace, long *count, int DEBUGMODE) { - - *count = 0; - char ret[maxstringlength]; - - std::string fluids(str); - std::string dlimit(search); - std::string substi(replace); - std::string result; - - // if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); - // if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); - // if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); - // if (DEBUGMODE) printf("nX: %li\n\n",*count); - - Poco::StringTokenizer tokens(fluids.c_str(), dlimit.c_str(), Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); - result = std::string(Poco::cat(substi, tokens.begin(), tokens.end())); - - strcpy(ret,result.c_str()); - //strcat(ret,'\0'); - - *count = tokens.count()-1; - - if (DEBUGMODE) printf("fluidnames: %s\n",fluids.c_str()); - if (DEBUGMODE) printf("delimiter: %s\n",dlimit.c_str()); - if (DEBUGMODE) printf("replace: %s\n",substi.c_str()); - if (DEBUGMODE) printf("replaced: %s\n",result.c_str()); - if (DEBUGMODE) printf("nX: %li\n\n",*count); - -return ret; - -} - -// char printDoubleArray (double* arr[] ) { -// std::copy(arr.begin(),arr.end(),std::ostream_iterator(std::cout,", ")); -// } - -char *printX(double arr[], long nX) { - char ret[filepathlength]; - char tmp[filepathlength]; - strcpy(ret,"("); - //for(int i = 0; i < (sizeof(arr)-1); i++) { - for(int i = 0; i < (nX-2); i++) { - sprintf(tmp,"%f, ", arr[i]); - strcat(ret,tmp); - } - sprintf(tmp,"%f", arr[nX-1]); - strcat(ret,tmp); - - strcat(ret,")"); - //printf ("output: %s \n", ret); - return ret; -} - -int init_REFPROP(char* fluidnames, char* REFPROP_PATH_CHAR, long* nX, char* herr, char* errormsg, int DEBUGMODE){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP -// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - - long ierr=0; -// DEBUGMODE = 1; - - if (strlen(REFPROP_PATH_CHAR)>filepathlength){ - sprintf(errormsg,"REFPROP_PATH_CHAR too long (%i > %li)\n",strlen(REFPROP_PATH_CHAR),filepathlength); - return 0; - } - // Define temporary objects for checks. - char REF_PATH_CHAR[filepathlength]; - Poco::Path REF_PATH(true); - char FLUIDS_CHAR[filepathlength] = "fluids"; - Poco::Path FLD_PATH(true); - char LIBRARY_CHAR[filepathlength]; - Poco::Path LIB_PATH(true); - //Poco::File theFile; - - // Parse the string and append a path separator if necessary. - REF_PATH.parse(REFPROP_PATH_CHAR, Poco::Path::PATH_NATIVE); - if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); - // Overwrite the provided path - strcpy(REF_PATH_CHAR,REF_PATH.toString().c_str()); - - // Check the path if running in debugmode - if (DEBUGMODE) { - Poco::File refFile(REF_PATH); - if ( !refFile.isDirectory() || !refFile.canRead() ){ - printf ("REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - sprintf (errormsg,"REF_PATH is not a readable directory: %s \n", REF_PATH.toString().c_str()); - return 0; - } else { - printf ("REF_PATH is a readable directory: %s \n", REF_PATH.toString().c_str()); - } - } - - // The fluid files are in the Refprop directory, append "fluids". - FLD_PATH.parse(REF_PATH_CHAR); - FLD_PATH.pushDirectory(FLUIDS_CHAR); - -// //std::string path(REF_PATH_CHAR); // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... -// Poco::Path SRC_PATH; -// SRC_PATH.parse(Poco::Environment::get("PATH")); - -// if (DEBUGMODE) { -// // Determine which library file should be loaded -// bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); -// if (is_linux){ -// strcpy(LIBRARY_CHAR,"librefprop.so"); -// SRC_PATH.pushDirectory("/usr/local/lib"); -// } else { -// strcpy(LIBRARY_CHAR,"refprop.dll"); -// SRC_PATH.pushDirectory(REF_PATH.toString()); -// } - - - //bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); -// if (found_lib) { -// printf ("Found library %s in path %s \n", LIBRARY_CHAR, path.c_str()); -// } else { -// printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, path.c_str()); -// } -// } else { -// LIB_PATH.parse(REF_PATH_CHAR); -// } - - //LIB_PATH.parse(LIBRARY_CHAR); - -// if (DEBUGMODE) { -// printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); -// printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); -// printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); -// printf ("Running OS family : %s \n\n", Poco::Environment::osName().c_str()); -// } - - Poco::Path SRC_PATH; // This is not fail-safe, the OS might look somewhere else, e.g. /usr/lib ... - - if (RefpropdllInstance==NULL) { // we need to load the library - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n", "false"); - - // Check the OS and assign the right names for the library - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - strcpy(LIBRARY_CHAR,"librefprop.so"); - SRC_PATH.parse("/usr/local/lib"); - } else { - strcpy(LIBRARY_CHAR,"refprop.dll"); - SRC_PATH = REF_PATH; - } - - // search the library at the given path - bool found_lib = Poco::Path::find(SRC_PATH.toString(), LIBRARY_CHAR, LIB_PATH); - if (found_lib) { - if (DEBUGMODE) printf ("Found library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - } else { - if (DEBUGMODE) printf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - sprintf ("Cannot find library %s in path %s \n", LIBRARY_CHAR, SRC_PATH.toString().c_str()); - return 0; - } - - // check if the file is correct and executable - if (DEBUGMODE) { - Poco::File libFile(LIB_PATH); - if ( !libFile.isFile() || !libFile.canRead() ){ - printf ("LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - sprintf (errormsg,"LIB_PATH is not a readable file: %s \n", LIB_PATH.toString().c_str()); - return 0; - } else { - printf ("LIB_PATH exists and is readable: %s \n", LIB_PATH.toString().c_str()); - } - } - - // load a new library instance - RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); - - } else { // library was already loaded - if (DEBUGMODE) printf ("RefpropdllInstance loaded: %s \n\n", "true"); - } - - // Now the library is loaded and we can start checkicng the fluid path - if (DEBUGMODE) { - Poco::File fldFile(FLD_PATH); - if ( !fldFile.isDirectory() || !fldFile.canRead() ){ - printf ("FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return 0; - } else { - printf ("FLD_PATH is a readable directory: %s \n", FLD_PATH.toString().c_str()); - } - } - char FLD_PATH_CHAR[filepathlength]; - strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - - - if (DEBUGMODE) { - printf ("%s\n"," "); - printf ("REF_PATH as string: %s \n", REF_PATH.toString().c_str()); - printf ("FLD_PATH as string: %s \n", FLD_PATH.toString().c_str()); - printf ("LIB_PATH as string: %s \n", LIB_PATH.toString().c_str()); - printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); - printf ("%s\n"," "); - } - - - // Check for new fluids and if the library has to be loaded again. - bool isFluid = (strcmp(fluidnames,loadedfluids)==0); - bool isPath = (strcmp(REF_PATH_CHAR,loadedpath)==0); - if (DEBUGMODE) printf ("Comparison of fluids : %i \n", isFluid ); - if (DEBUGMODE) printf ("Comparison of path : %i \n\n", isPath ); - //if (DEBUGMODE) printf ("Checking setup : %s and %s \n\n", REF_PATH_CHAR,loadedpath ); - - char *hf; - -// // // // if (isFluid && isPath) { -// // // // //sprintf(errormsg,"Library is already loaded: %s \n",LIB_PATH.toString().c_str()); -// // // // if (DEBUGMODE) printf ("No setup needed, fluids (%s) and path (%s) did not change.\n\n", fluidnames,REF_PATH_CHAR); -// // // // // // // // return 0; -// // // // } else { - // we need to call setup - - char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; -// // // // char *hf; - - //parse fluid composition string and insert absolute paths - char replace[filepathlength+6]; - strcpy(replace,".FLD|"); - //if (DEBUGMODE) printf("REPLACE: %s\n",replace); - strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); - - //int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; - int hf_len = maxstringlength; - hf = (char*) calloc(hf_len, sizeof(char)); - - strncpy(hf,FLD_PATH_CHAR,hf_len); - - char replaced[filepathlength]; - - strcpy(replaced,str_replace(fluidnames, "|", replace, nX, DEBUGMODE)); - - //str_replace returns the number of delimiters -> nX, but components are one more ... - if (++*nX>ncmax){ //...that's why nX is incremented - sprintf(errormsg,"Too many components (More than %li)\n",ncmax); - return 0; - } - - - strncat(hf,replaced,hf_len-strlen(hf)); - - strncat(hf,".FLD",hf_len-strlen(hf)); - - if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); - - strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path - strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); - strcpy(hrf,"DEF"); - - - SETUPdll_POINTER SETUP = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); - if (DEBUGMODE) printf("Running SETUP...\n"); - //char hftmp[maxstringlength]; - //strcpy(hftmp,hf); - static char hfld[maxstringlength+1]; - strcpy(hfld,hf); - SETUP(*nX, hfld, hfmix, hrf, ierr, herr); - - strcpy(loadedfluids,fluidnames); - strcpy(loadedpath,REF_PATH_CHAR); - if (DEBUGMODE) printf("SETUP run complete (Error no: %li)\n",ierr); - - if (DEBUGMODE) printf("Error code processing...\n"); - switch(ierr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening file %s",hf); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - strncpy(errormsg,herr,errormessagelength); - break; - } -// // // // free(hf); - return ierr; - - -// if (DEBUGMODE) { -// theFile = Poco::File(LIB_PATH); -// if ( !theFile.isFile() || !theFile.canExecute() ){ -// sprintf (errormsg,"LIB_PATH is not an executable file: %s \n", LIB_PATH.toString().c_str()); -// return 0; -// } -// } -// char LIB_PATH_CHAR[filepathlength]; -// strcpy(LIB_PATH_CHAR,LIB_PATH.toString().c_str()); -// -// if (DEBUGMODE) { -// theFile = Poco::File(FLD_PATH); -// if ( !theFile.isDirectory() || !theFile.canRead() ){ -// sprintf (errormsg,"FLD_PATH is not a readable directory: %s \n", FLD_PATH.toString().c_str()); -// return 0; -// } -// } -// char FLD_PATH_CHAR[filepathlength]; -// strcpy(FLD_PATH_CHAR,FLD_PATH.toString().c_str()); - -//// First we load the library with the POCO foundation -//// classes and then define all the needed functions -//// by their names and a cast to the correct type. -// if (DEBUGMODE) printf ("RefpropdllInstance loaded path: %s \n", RefpropdllInstance.getPath().c_str()); -// if (DEBUGMODE) printf ("New path for loading the library: %s \n", LIB_PATH.toString().c_str()); -// if (DEBUGMODE) printf ("Comparison: %i \n", LIB_PATH.toString().compare(RefpropdllInstance.getPath()) ); -// if ( LIB_PATH.toString().compare(RefpropdllInstance.getPath())!=0 ) { -// RefpropdllInstance.unload(); -// if (DEBUGMODE) printf ("RefpropdllInstance unloaded: %s \n", "true"); -// RefpropdllInstance.load(LIB_PATH_CHAR); -// } -// -// if (!RefpropdllInstance.isLoaded()){ -// sprintf(errormsg,"ERROR in opening library at \"%s\"",LIB_PATH_CHAR); -// return 100; -// } - - -// char hrf[lengthofreference+1],hfmix[filepathlength+1+7]; -// char *hf; -// -// //parse fluid composition string and insert absolute paths -// char replace[filepathlength+6]; -// strcpy(replace,".FLD|"); -// //if (DEBUGMODE) printf("REPLACE: %s\n",replace); -// strncat(replace, FLD_PATH_CHAR,filepathlength-strlen(replace)); -// -// int hf_len = strlen(fluidnames)+ncmax*(strlen(replace)-1)+4; -// hf = (char*) calloc(hf_len, sizeof(char)); -// -// strncpy(hf,FLD_PATH_CHAR,hf_len); -// strncat(hf,str_replace(fluidnames, "|", replace, nX),hf_len-strlen(hf)); //str_replace returns the number of delimiters -> nX, but components are one more ... -// if (++*nX>ncmax){ //...that's why nX is incremented -// sprintf(errormsg,"Too many components (More than %i)\n",ncmax); -// return 0; -// } -// strncat(hf,".FLD",hf_len-strlen(hf)); -// if (DEBUGMODE) printf("Fluid composition string: \"%s\"\n",hf); -// -// strncpy(hfmix,FLD_PATH_CHAR,filepathlength+1);//add absolute path -// strncat(hfmix,"hmx.bnc",filepathlength+1+7-strlen(hfmix)); -// strcpy(hrf,"DEF"); -// -// -// // SETUPdll_TYPE * SETUPdll = (SETUPdll_TYPE * ) RefpropdllInstance.getSymbol(SETUPdll_NAME); -// if (DEBUGMODE) printf("Running SETUPdll...\n"); -// SETUP(*nX, hf, hfmix, hrf, ierr, herr); -// strcpy(loadedfluids,fluidnames); -// if (DEBUGMODE) printf("SETUPdll run complete (Error no: %i)\n",ierr); -// -// // WMOLdll = (WMOLdll_POINTER) RefpropdllInstance.getSymbol(WMOLdll_NAME); -// // TPFL2dll = (TPFL2dll_POINTER) RefpropdllInstance.getSymbol(TPFL2dll_NAME); -// // TPFLSHdll = (TPFLSHdll_POINTER) RefpropdllInstance.getSymbol(TPFLSHdll_NAME); -// // PHFL1dll = (PHFL1dll_POINTER) RefpropdllInstance.getSymbol(PHFL1dll_NAME); -// // PHFLSHdll = (PHFLSHdll_POINTER) RefpropdllInstance.getSymbol(PHFLSHdll_NAME); -// // PDFL1dll = (PDFL1dll_POINTER) RefpropdllInstance.getSymbol(PDFL1dll_NAME); -// // PDFLSHdll = (PDFLSHdll_POINTER) RefpropdllInstance.getSymbol(PDFLSHdll_NAME); -// // PSFLSHdll = (PSFLSHdll_POINTER) RefpropdllInstance.getSymbol(PSFLSHdll_NAME); -// // PQFLSHdll = (PQFLSHdll_POINTER) RefpropdllInstance.getSymbol(PQFLSHdll_NAME); -// // THFLSHdll = (THFLSHdll_POINTER) RefpropdllInstance.getSymbol(THFLSHdll_NAME); -// // TDFLSHdll = (TDFLSHdll_POINTER) RefpropdllInstance.getSymbol(TDFLSHdll_NAME); -// // TSFLSHdll = (TSFLSHdll_POINTER) RefpropdllInstance.getSymbol(TSFLSHdll_NAME); -// // TQFLSHdll = (TQFLSHdll_POINTER) RefpropdllInstance.getSymbol(TQFLSHdll_NAME); -// // DHFL1dll = (DHFL1dll_POINTER) RefpropdllInstance.getSymbol(DHFL1dll_NAME); -// // DHFL2dll = (DHFL2dll_POINTER) RefpropdllInstance.getSymbol(DHFL2dll_NAME); -// // DHFLSHdll = (DHFLSHdll_POINTER) RefpropdllInstance.getSymbol(DHFLSHdll_NAME); -// // HSFLSHdll = (HSFLSHdll_POINTER) RefpropdllInstance.getSymbol(HSFLSHdll_NAME); -// // DSFL1dll = (DSFL1dll_POINTER) RefpropdllInstance.getSymbol(DSFL1dll_NAME); -// // DSFL2dll = (DSFL2dll_POINTER) RefpropdllInstance.getSymbol(DSFL2dll_NAME); -// // DSFLSHdll = (DSFLSHdll_POINTER) RefpropdllInstance.getSymbol(DSFLSHdll_NAME); -// // TRNPRPdll = (TRNPRPdll_POINTER) RefpropdllInstance.getSymbol(TRNPRPdll_NAME); -// // SATTdll = (SATTdll_POINTER) RefpropdllInstance.getSymbol(SATTdll_NAME); -// // SATPdll = (SATPdll_POINTER) RefpropdllInstance.getSymbol(SATPdll_NAME); -// // SATDdll = (SATDdll_POINTER) RefpropdllInstance.getSymbol(SATDdll_NAME); - - -// // if (DEBUGMODE) printf("Error code processing...\n"); -// switch(ierr){ -// case 101: -// //strcpy(errormsg,"error in opening file"); -// // if (DEBUGMODE) printf("Error 101\n"); -// sprintf(errormsg,"error in opening file %s",hf); -// break; -// case 102: -// // if (DEBUGMODE) printf("Error 102\n"); -// strcpy(errormsg,"error in file or premature end of file"); -// break; -// case -103: -// // if (DEBUGMODE) printf("Error -103\n"); -// strcpy(errormsg,"unknown model encountered in file"); -// break; -// case 104: -// // if (DEBUGMODE) printf("Error 104\n"); -// strcpy(errormsg,"error in setup of model"); -// break; -// case 105: -// // if (DEBUGMODE) printf("Error 105\n"); -// strcpy(errormsg,"specified model not found"); -// break; -// case 111: -// // if (DEBUGMODE) printf("Error 111\n"); -// strcpy(errormsg,"error in opening mixture file"); -// break; -// case 112: -// // if (DEBUGMODE) printf("Error 112\n"); -// strcpy(errormsg,"mixture file of wrong type"); -// break; -// case 114: -// // if (DEBUGMODE) printf("Error 114\n"); -// strcpy(errormsg,"nc<>nc from setmod"); -// break; -// case 0: -// break; -// default: -// // if (DEBUGMODE) printf("Unknown error\n"); -// strcpy(errormsg,"Unknown error"); -// //strcpy(errormsg,"Setup was successful!"); -// strncpy(errormsg,herr,errormessagelength); -// break; -// } -// free(hf); -// return ierr; -} - - -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevars: string of any combination of two variables out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevar1,statevar2: values of the two variables specified in statevars - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values (props[0] containing error number) - errormsg: string containing error message -*/ - char statevars[3]; - double p, T, d, val, dl,dv,q,e,h,s,cv,cp,w,wm,wmliq,wmvap,eta,tcx; - long nX,ierr=0; //zero means no error - char herr[errormessagelength+1]; -// HINSTANCE RefpropdllInstance;// Then have windows load the library. -// Poco::SharedLibrary RefpropdllInstance(""); - -// DEBUGMODE = 1; - - if (DEBUGMODE) printf("\nStarting function props_REFPROP to calc %c...\n", what[0]); - - //initialize interface to REFPROP.dll -// if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, &RefpropdllInstance, errormsg, DEBUGMODE)){ -// printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); -// return 0; -// } - if(props[0]=(double)init_REFPROP(fluidnames, REFPROP_PATH, &nX, herr, errormsg, DEBUGMODE)){ - printf("Error no. %g initializing REFPROP: \"%s\"\n", props[0], errormsg); - return 0; - } - - //CALCULATE MOLAR MASS -// WMOL = (fp_WMOLdllTYPE) GetProcAddress(RefpropdllInstance,"WMOLdll"); -// WMOLdll_TYPE * WMOL = (WMOLdll_TYPE * ) RefpropdllInstance.getSymbol(WMOLdll_NAME); - WMOL = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); - WMOL(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - wm /= 1000; //g/mol -> kg/mol - - //identify and assign passed state variables - statevars[0] = tolower(statevars_in[0]); - statevars[1] = tolower(statevars_in[1]); - statevars[2] = '\0'; - if (statevars[0]!='\0'){ - if (statevars[0]==statevars[1]){ - props[0] = 3; - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%c)",statevars[0]); - return 0; - } - for (int ii=0;ii<2;ii++){ - val = (ii==0?statevar1:statevar2); - switch(statevars[ii]){ - case 'p': - p = val/1000; //Pa->kPa - break; - case 't': - T = val; - break; - case 's': - s = val*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = val*wm; //J/kg --> kJ/mol - break; - case 'd': - d = val/wm/1000; //kg/m� -> mol/dm� - break; - case 'q': //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - q = val; - break; - default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable %i: %c",ii+1 ,statevars[ii]);/**/ - return 0; - } - } - } - -/* -//...If phase j is known, call TPRHO: - long j=2; //phase definition(j=1: Liquid, j=2: Vapor) - long tmp_int=0; - TPRHOdll = (fp_TPRHOdllTYPE) GetProcAddress(RefpropdllInstance,"TPRHOdll"); - TPRHO(t,p,x,j,tmp_int,d,ierr,herr,errormessagelength); -*/ -//...If phase is not known, call TPFLSH - double xliq[ncmax],xvap[ncmax],f[ncmax]; - long kq=2;/* additional input--only for TQFLSH and PQFLSH - kq--flag specifying units for input quality - kq = 1 quality on MOLAR basis [moles vapor/total moles] - kq = 2 quality on MASS basis [mass vapor/total mass]*/ -// sprintf(errormsg,"Huhu! %s %d", statevars, ierr); - if (ierr==0){ - if (strcmp(statevars,"pt")==0 || strcmp(statevars,"tp")==0){ -// strcat(errormsg,"Bin in TP!"); - if (phase==2){ //fluid state is known to be two phase -// TPFL2dll = (fp_TPFL2dllTYPE) GetProcAddress(RefpropdllInstance,"TPFL2dll"); - TPFL2 = (TPFL2dll_POINTER) RefpropdllInstance->getSymbol(TPFL2dll_NAME); - TPFL2(T,p,x,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - }else{ -// TPFLSHdll = (fp_TPFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TPFLSHdll"); - TPFLSH = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); - TPFLSH(T,p,x,d,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ph")==0 || strcmp(statevars,"hp")==0){ -// if (phase==1){ //fluid state is known to be single phase -//// PHFL1dll = (fp_PHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PHFL1dll"); -// PHFL1 = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); -// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); -//// if (liqvap==1) dl=d; else dv=d; -// }else{ -//// PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - PHFLSH = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); - PHFLSH(p,h,x,T,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pd")==0 || strcmp(statevars,"dp")==0){ - if (phase==1){ //fluid state is known to be single phase -// PDFL1dll = (fp_PDFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PDFL1dll"); - PDFL1 = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); - PDFL1(p,d,x,T,ierr,herr,errormessagelength); - }else{ -// PDFLSHdll = (fp_PDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PDFLSHdll"); - PDFLSH = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); - PDFLSH(p,d,x,T,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - } - }else if (strcmp(statevars,"ps")==0 || strcmp(statevars,"sp")==0){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1dll = (fp_PSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"PSFL1dll"); - PSFL1(p,s,x,kph,T,d,ierr,herr,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ -// PSFLSHdll = (fp_PSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PSFLSHdll"); - PSFLSH = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); - PSFLSH(p,s,x,T,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"pq")==0 || strcmp(statevars,"qp")==0){ -// PQFLSHdll = (fp_PQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PQFLSHdll"); - PQFLSH = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); - PQFLSH(p,q,x,kq,T,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (strcmp(statevars,"th")==0 || strcmp(statevars,"ht")==0){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1dll = (fp_THFL1dllTYPE) GetProcAddress(RefpropdllInstance,"THFL1dll"); - THFL1(T,h,x,Dmin,Dmax,d,ierr,herr,errormessagelength); - }else{*/ -// THFLSHdll = (fp_THFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"THFLSHdll"); - THFLSH = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - THFLSH (T,h,x,kr,p,d,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); -// } - }else if (strcmp(statevars,"td")==0 || strcmp(statevars,"dt")==0){ -// TDFLSHdll = (fp_TDFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - TDFLSH = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); - TDFLSH(T,d,x,p,dl,dv,xliq,xvap,q,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ts")==0 || strcmp(statevars,"st")==0){ -// TSFLSHdll = (fp_TSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TSFLSHdll"); - TSFLSH = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); - long kr = 2; - TSFLSH(T,s,x,kr,p,d,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"tq")==0 || strcmp(statevars,"qt")==0){ -// TQFLSHdll = (fp_TQFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"TQFLSHdll"); - TQFLSH = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); - TQFLSH(T,q,x,kq,p,d,dl,dv,xliq,xvap,e,h,s,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"hd")==0 || strcmp(statevars,"dh")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DHFL1dll = (fp_DHFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL1dll"); - DHFL1 = (DHFL1dll_POINTER) RefpropdllInstance->getSymbol(DHFL1dll_NAME); - DHFL1(d,h,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DHFL2dll = (fp_DHFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DHFL2dll"); - DHFL2 = (DHFL2dll_POINTER) RefpropdllInstance->getSymbol(DHFL2dll_NAME); - DHFL2(d,h,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DHFLSHdll = (fp_DHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DHFLSHdll"); - DHFLSH = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); - DHFLSH(d,h,x,T,p,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); - break; - } - }else if (strcmp(statevars,"hs")==0 || strcmp(statevars,"sh")==0){ -// HSFLSHdll = (fp_HSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"HSFLSHdll"); - HSFLSH = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); - HSFLSH(h,s,x,T,p,d,dl,dv,xliq,xvap,q,e,cv,cp,w,ierr,herr,errormessagelength); - }else if (strcmp(statevars,"ds")==0 || strcmp(statevars,"sd")==0){ - switch(phase){ //fluid state is known to be single phase - case 1: -// DSFL1dll = (fp_DSFL1dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL1dll"); - DSFL1 = (DSFL1dll_POINTER) RefpropdllInstance->getSymbol(DSFL1dll_NAME); - DSFL1(d,s,x,T,ierr,herr,errormessagelength); - break; - case 2: -// DSFL2dll = (fp_DSFL2dllTYPE) GetProcAddress(RefpropdllInstance,"DSFL2dll"); - DSFL2 = (DSFL2dll_POINTER) RefpropdllInstance->getSymbol(DSFL2dll_NAME); - DSFL2(d,s,x,T,p,dl,dv,xliq,xvap,q,ierr,herr,errormessagelength); - break; - default: -// DSFLSHdll = (fp_DSFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"DSFLSHdll"); - DSFLSH = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); - DSFLSH(d,s,x,T,p,dl,dv,xliq,xvap,q,e,h,cv,cp,w,ierr,herr,errormessagelength); - break; - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s", statevars); - } - - switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE - case 'v': //dynamic viscosity uPa.s - case 'l': //thermal conductivity W/m.K -// TRNPRPdll = (fp_TRNPRPdllTYPE) GetProcAddress(RefpropdllInstance,"TRNPRPdll"); - TRNPRP = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); - TRNPRP(T,d,x,eta,tcx,ierr,herr,errormessagelength); - break; - } - - - switch(ierr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 4: - sprintf(errormsg,"P=%f < 0",p); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",T,p); - break; - case 8: - sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(x,nX)); - break; - case 9: - sprintf(errormsg,"x=%s or T=%f out of range",printX(x,nX),T); - break; - case 12: - sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(x,nX),p); - break; - case 13: - sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(x,nX),T,p); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",T); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",d); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",T,d); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",T); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",d); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",T,d); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",T); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",d); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",T,d); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",T); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - break; - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",d,s); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",h); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",T); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",T); - break; - default: - strncpy(errormsg,herr,errormessagelength); - break; - } - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOL(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOL(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� - e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) - cv /= wm; - cp /= wm; - p *= 1000; //kPa->Pa - if (nX>1 && abs(q)<990) q *= wmvap/wm; //molar bass -> mass basis - eta/=1e6; //uPa.s -> Pa.s - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = q; //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = e; //inner energy - props[9] = h; //specific enthalpy - props[10] = s;//specific entropy - props[11] = cv; - props[12] = cp; - props[13] = w; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;iigetSymbol(WMOLdll_NAME); - WMOL(x,wm); -// sprintf(errormsg," %10.4f, %10.4f, %10.4f,",x[0],x[1],wm); - if (DEBUGMODE) printf("\nFunction WMOLdll was called\n"); - - wm /= 1000; //g/mol -> kg/mol - - if (DEBUGMODE) printf("wm converted.\n"); - - if (DEBUGMODE) printf("statevar is %s \n",statevar_in); - //identify and assign passed state variables - // char tmpstr[1]; - // strcpy(tmpstr,statevar[0]); - // statevar = toLowerCase(tmpstr); - //statevar[0] = tolower(statevar[0]); - char statevar[1]; - statevar[0] = tolower(statevar_in[0]); - if (DEBUGMODE) printf("\nstatevar lowercase.\n"); - if (statevar[0]!='\0'){ -// if (strcmp(statevar[0],"")){ -// if (statevar[0] != NULL){ - if (DEBUGMODE) printf("\nentering statevar switch.\n"); - switch(statevar[0]){ - case 'p': - p = statevarval/1000; //Pa->kPa - break; - case 't': - T = statevarval; - break; - case 'd': - d = statevarval/wm/1000; //kg/m� -> mol/dm� - break; -/* case 's': - s = statevarval*wm; //J/(kg�K) -> kJ/(mol�K) - break; - case 'h': - h = statevarval*wm; //J/kg --> kJ/mol - break; -*/ default: - props[0] = 2; - sprintf(errormsg,"Unknown state variable: %f", statevarval); - return 0; - } - } - - if (DEBUGMODE) printf("\nstatevar checked.\n"); - - double xliq[ncmax],xvap[ncmax],f[ncmax]; - - long j=2,kr; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - if (ierr==0) { - if (~strcmp(statevar,"t")){ -// SATTdll = (fp_SATTdllTYPE) GetProcAddress(RefpropdllInstance,"SATTdll"); - SATT = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); - SATT(T,x,j,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - }else if (~strcmp(statevar,"p")){ -// SATPdll = (fp_SATPdllTYPE) GetProcAddress(RefpropdllInstance,"SATPdll"); - SATP = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); - SATP(p,x,j,T,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - }else if (~strcmp(statevar,"d")){ -// SATDdll = (fp_SATDdllTYPE) GetProcAddress(RefpropdllInstance,"SATDdll"); - SATD = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); - SATD(d,x,j,kr,T,p,dl,dv,xliq,xvap,ierr,herr,errormessagelength); - switch(ierr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - } - - switch(ierr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",T); - break; - case 8: - sprintf(errormsg,"x out of range, %s",printX(x,nX)); - break; - case 9: - sprintf(errormsg,"T=%f and x=%s out of range",T,printX(x,nX)); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - strncpy(errormsg,herr,errormessagelength); - break; - } - - /*SATHdll = (fp_SATHdllTYPE) GetProcAddress(RefpropdllInstance,"SATHdll"); - SATEdll = (fp_SATEdllTYPE) GetProcAddress(RefpropdllInstance,"SATEdll"); - SATSdll = (fp_SATSdllTYPE) GetProcAddress(RefpropdllInstance,"SATSdll");*/ - - - //CONVERT TO SI-UNITS - if (ierr==0){ - WMOL(xliq,wmliq); - wmliq /= 1000; //g/mol -> kg/mol - WMOL(xvap,wmvap); - wmvap /= 1000; //g/mol -> kg/mol - //printf("%d,%s\n%s\nP,T,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",nX,hf,hfmix,p,t,d,h,wm); - d *= wm*1000; //mol/dm� -> kg/m� - dl *= wmliq*1000; //mol/dm� -> kg/m� - dv *= wmvap*1000; //mol/dm� -> kg/m� -/* e /= e/wm; //kJ/mol -> J/kg - h /= wm; //kJ/mol -> J/kg - s /= wm; //kJ/(mol�K) -> J/(kg�K) -*/ p *= 1000; //kPa->Pa - } - - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = ierr;//error code - props[1] = p;//pressure in kPa->Pa - props[2] = T; //Temperature in K - props[3] = wm; //molecular weight - props[4] = d; //density - props[5] = dl; //density of liquid phase - props[6] = dv; //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0;//specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = wmliq; - props[15] = wmvap; - for (int ii=0;ii -#include -//#include "refprop_density_fixgas.h" -#include "refprop_wrapper.h" - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -void main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255+1024]; - double* x; - double *props; - double sumx; - int i; - int nX = argc-5; - - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); - return; - } - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - - - sumx = 0; - for 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
%76N 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
f7bWn*C}86`(T4kp6>(m858z%ZxW=@R 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 -// The other data types can be handled: -typedef long INTEGER; -typedef float REAL; -typedef double DOUBLE_PRECISION; -typedef int LOGICAL; -// -// Do some manual changes to the function names -// if needed. -#if defined(WIN32) || defined(_WIN32) -// Define compiler specific calling conventions -// for the shared library. -# define LIBRARY_API __stdcall // __declspec(dllexport) -// Do not define function names for the shared library, -// in this case it is the REFPROP.dll and no special -// names are needed. -# define RPVersion RPVersion -# define SETPATHdll SETPATHdll -# define ABFL1dll ABFL1dll -# define ABFL2dll ABFL2dll -# define ACTVYdll ACTVYdll -# define AGdll AGdll -# define CCRITdll CCRITdll -# define CP0dll CP0dll -# define CRITPdll CRITPdll -# define CSATKdll CSATKdll -# define CV2PKdll CV2PKdll -# define CVCPKdll CVCPKdll -# define CVCPdll CVCPdll -# define DBDTdll DBDTdll -# define DBFL1dll DBFL1dll -# define DBFL2dll DBFL2dll -# define DDDPdll DDDPdll -# define DDDTdll DDDTdll -# define DEFLSHdll DEFLSHdll -# define DHD1dll DHD1dll -# define DHFL1dll DHFL1dll -# define DHFL2dll DHFL2dll -# define DHFLSHdll DHFLSHdll -# define DIELECdll DIELECdll -# define DOTFILLdll DOTFILLdll -# define DPDD2dll DPDD2dll -# define DPDDKdll DPDDKdll -# define DPDDdll DPDDdll -# define DPDTKdll DPDTKdll -# define DPDTdll DPDTdll -# define DPTSATKdll DPTSATKdll -# define DSFLSHdll DSFLSHdll -# define DSFL1dll DSFL1dll -# define DSFL2dll DSFL2dll -# define ENTHALdll ENTHALdll -# define ENTROdll ENTROdll -# define ESFLSHdll ESFLSHdll -# define FGCTYdll FGCTYdll -# define FPVdll FPVdll -# define GERG04dll GERG04dll -# define GETFIJdll GETFIJdll -# define GETKTVdll GETKTVdll -# define GIBBSdll GIBBSdll -# define HSFLSHdll HSFLSHdll -# define INFOdll INFOdll -# define LIMITKdll LIMITKdll -# define LIMITSdll LIMITSdll -# define LIMITXdll LIMITXdll -# define MELTPdll MELTPdll -# define MELTTdll MELTTdll -# define MLTH2Odll MLTH2Odll -# define NAMEdll NAMEdll -# define PDFL1dll PDFL1dll -# define PDFLSHdll PDFLSHdll -# define PEFLSHdll PEFLSHdll -# define PHFL1dll PHFL1dll -# define PHFLSHdll PHFLSHdll -# define PQFLSHdll PQFLSHdll -# define PREOSdll PREOSdll -# define PRESSdll PRESSdll -# define PSFL1dll PSFL1dll -# define PSFLSHdll PSFLSHdll -# define PUREFLDdll PUREFLDdll -# define QMASSdll QMASSdll -# define QMOLEdll QMOLEdll -# define SATDdll SATDdll -# define SATEdll SATEdll -# define SATHdll SATHdll -# define SATPdll SATPdll -# define SATSdll SATSdll -# define SATTdll SATTdll -# define SETAGAdll SETAGAdll -# define SETKTVdll SETKTVdll -# define SETMIXdll SETMIXdll -# define SETMODdll SETMODdll -# define SETREFdll SETREFdll -# define SETUPdll SETUPdll -//# define SPECGRdll SPECGRdll // not found in library -# define SUBLPdll SUBLPdll -# define SUBLTdll SUBLTdll -# define SURFTdll SURFTdll -# define SURTENdll SURTENdll -# define TDFLSHdll TDFLSHdll -# define TEFLSHdll TEFLSHdll -# define THERM0dll THERM0dll -# define THERM2dll THERM2dll -# define THERM3dll THERM3dll -# define THERMdll THERMdll -# define THFLSHdll THFLSHdll -# define TPFLSHdll TPFLSHdll -# define TPFL2dll TPFL2dll -# define TPRHOdll TPRHOdll -# define TQFLSHdll TQFLSHdll -# define TRNPRPdll TRNPRPdll -# define TSFLSHdll TSFLSHdll -# define VIRBdll VIRBdll -# define VIRCdll VIRCdll -# define WMOLdll WMOLdll -# define XMASSdll XMASSdll -# define XMOLEdll XMOLEdll -#else // defined(WIN32) || defined(_WIN32) -// Define compiler specific calling conventions -// for the shared library. -# define LIBRARY_API -// Define function names for the shared library, -// in this case it is the librefprop.so and the -// names might change on some systems during -// the compilation of the Fortran files. -// Possible other branches for this code could be: -// # if !defined(_AIX) -// # if !defined(__hpux) -// # ifdef _CRAY -// However, I cannot test that and therefore do not include it. -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -//# define SPECGRdll specgrdll_ // not found in library -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -#endif // defined(WIN32) || defined(_WIN32), else branch -// -// -// define new macros for function names -// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value -#include -#define STR_VALUE(arg) #arg -#define FUNCTION_NAME(name) STR_VALUE(name) -// -// Prepare the strings to be used by the functions that -// handle the library later on. -#define RPVersion_NAME FUNCTION_NAME(RPVersion) -#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) -#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) -#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) -#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) -#define AGdll_NAME FUNCTION_NAME(AGdll) -#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) -#define CP0dll_NAME FUNCTION_NAME(CP0dll) -#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) -#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) -#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) -#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) -#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) -#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) -#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) -#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) -#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) -#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) -#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) -#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) -#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) -#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) -#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) -#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) -#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) -#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) -#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) -#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) -#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) -#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) -#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) -#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) -#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) -#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) -#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) -#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) -#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) -#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) -#define FPVdll_NAME FUNCTION_NAME(FPVdll) -#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) -#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) -#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) -#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) -#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) -#define INFOdll_NAME FUNCTION_NAME(INFOdll) -#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) -#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) -#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) -#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) -#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) -#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) -#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) -#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) -#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) -#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) -#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) -#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) -#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) -#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) -#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) -#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) -#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) -#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) -#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) -#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) -#define SATDdll_NAME FUNCTION_NAME(SATDdll) -#define SATEdll_NAME FUNCTION_NAME(SATEdll) -#define SATHdll_NAME FUNCTION_NAME(SATHdll) -#define SATPdll_NAME FUNCTION_NAME(SATPdll) -#define SATSdll_NAME FUNCTION_NAME(SATSdll) -#define SATTdll_NAME FUNCTION_NAME(SATTdll) -#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) -#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) -#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) -#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) -#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) -#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) -//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library -#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) -#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) -#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) -#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) -#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) -#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) -#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) -#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) -#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) -#define THERMdll_NAME FUNCTION_NAME(THERMdll) -#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) -#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) -#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) -#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) -#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) -#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) -#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) -#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) -#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) -#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) -#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) -#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) -// -// I'll try to follow this example from: -// http://www.gershnik.com/tips/cpp.asp -// function type: typedef void [compiler stuff] func_t(int, float); -// function declaration: func_t func; -// pointer type: typedef func_t * func_ptr; -#ifdef __cplusplus -extern "C" { -#endif - // extra function for setup - typedef void (LIBRARY_API RPVersion_TYPE )( char* ); - typedef void (LIBRARY_API SETPATHdll_TYPE)( const char* ); - // - typedef void (LIBRARY_API ABFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ABFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API ACTVYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API AGdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CCRITdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CP0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CRITPdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CV2PKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API CVCPKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API CVCPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DBFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DBFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DDDPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DDDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DHD1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DIELECdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DOTFILLdll_TYPE)(INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DPDD2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPDTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API DPTSATKdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API DSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API DSFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API ENTHALdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ENTROdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API ESFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API FGCTYdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *); - typedef void (LIBRARY_API FPVdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API GERG04dll_TYPE)(INTEGER &,INTEGER &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API GETFIJdll_TYPE)(char*,DOUBLE_PRECISION *,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API GIBBSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API HSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API INFOdll_TYPE)(INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API LIMITKdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API LIMITSdll_TYPE)(char*,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER ); - typedef void (LIBRARY_API LIMITXdll_TYPE)(char*,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - typedef void (LIBRARY_API MELTPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MELTTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API MLTH2Odll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API NAMEdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API PDFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PHFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PREOSdll_TYPE)(INTEGER &); - typedef void (LIBRARY_API PRESSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API PSFL1dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API PUREFLDdll_TYPE)(INTEGER &); - typedef void (LIBRARY_API QMASSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API QMOLEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATDdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATEdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATSdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SATTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETAGAdll_TYPE)(INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SETKTVdll_TYPE)(INTEGER &,INTEGER &,char*,DOUBLE_PRECISION *,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMIXdll_TYPE)(char*,char*,char*,INTEGER &,char*,DOUBLE_PRECISION *,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETMODdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETREFdll_TYPE)(char*,INTEGER &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ,INTEGER ); - //typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*,INTEGER ,INTEGER ,INTEGER ,INTEGER ); - typedef void (LIBRARY_API SETUPdll_TYPE)(INTEGER &,char*,char*,char*,INTEGER &,char*); -// typedef void (LIBRARY_API SPECGRdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); // not found in library - typedef void (LIBRARY_API SUBLPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SUBLTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURFTdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API SURTENdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TDFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TEFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API THERM0dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERM3dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THERMdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &); - typedef void (LIBRARY_API THFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TPFL2dll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER );//added by henning francke - typedef void (LIBRARY_API TPRHOdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,INTEGER &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TQFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TRNPRPdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API TSFLSHdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,INTEGER &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,DOUBLE_PRECISION &,INTEGER &,char*,INTEGER ); - typedef void (LIBRARY_API VIRBdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API VIRCdll_TYPE)(DOUBLE_PRECISION &,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API WMOLdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMASSdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - typedef void (LIBRARY_API XMOLEdll_TYPE)(DOUBLE_PRECISION *,DOUBLE_PRECISION *,DOUBLE_PRECISION &); - // - // Declare the functions for direct access - RPVersion_TYPE RPVersion; - SETPATHdll_TYPE SETPATHdll; - ABFL1dll_TYPE ABFL1dll; - ABFL2dll_TYPE ABFL2dll; - ACTVYdll_TYPE ACTVYdll; - AGdll_TYPE AGdll; - CCRITdll_TYPE CCRITdll; - CP0dll_TYPE CP0dll; - CRITPdll_TYPE CRITPdll; - CSATKdll_TYPE CSATKdll; - CV2PKdll_TYPE CV2PKdll; - CVCPKdll_TYPE CVCPKdll; - CVCPdll_TYPE CVCPdll; - DBDTdll_TYPE DBDTdll; - DBFL1dll_TYPE DBFL1dll; - DBFL2dll_TYPE DBFL2dll; - DDDPdll_TYPE DDDPdll; - DDDTdll_TYPE DDDTdll; - DEFLSHdll_TYPE DEFLSHdll; - DHD1dll_TYPE DHD1dll; - DHFLSHdll_TYPE DHFLSHdll; - DHFL1dll_TYPE DHFL1dll; - DHFL2dll_TYPE DHFL2dll; - DIELECdll_TYPE DIELECdll; - DOTFILLdll_TYPE DOTFILLdll; - DPDD2dll_TYPE DPDD2dll; - DPDDKdll_TYPE DPDDKdll; - DPDDdll_TYPE DPDDdll; - DPDTKdll_TYPE DPDTKdll; - DPDTdll_TYPE DPDTdll; - DPTSATKdll_TYPE DPTSATKdll; - DSFLSHdll_TYPE DSFLSHdll; - DSFL1dll_TYPE DSFL1dll; - DSFL2dll_TYPE DSFL2dll; - ENTHALdll_TYPE ENTHALdll; - ENTROdll_TYPE ENTROdll; - ESFLSHdll_TYPE ESFLSHdll; - FGCTYdll_TYPE FGCTYdll; - FPVdll_TYPE FPVdll; - GERG04dll_TYPE GERG04dll; - GETFIJdll_TYPE GETFIJdll; - GETKTVdll_TYPE GETKTVdll; - GIBBSdll_TYPE GIBBSdll; - HSFLSHdll_TYPE HSFLSHdll; - INFOdll_TYPE INFOdll; - LIMITKdll_TYPE LIMITKdll; - LIMITSdll_TYPE LIMITSdll; - LIMITXdll_TYPE LIMITXdll; - MELTPdll_TYPE MELTPdll; - MELTTdll_TYPE MELTTdll; - MLTH2Odll_TYPE MLTH2Odll; - NAMEdll_TYPE NAMEdll; - PDFL1dll_TYPE PDFL1dll; - PDFLSHdll_TYPE PDFLSHdll; - PEFLSHdll_TYPE PEFLSHdll; - PHFL1dll_TYPE PHFL1dll; - PHFLSHdll_TYPE PHFLSHdll; - PQFLSHdll_TYPE PQFLSHdll; - PREOSdll_TYPE PREOSdll; - PRESSdll_TYPE PRESSdll; - PSFL1dll_TYPE PSFL1dll; - PSFLSHdll_TYPE PSFLSHdll; - PUREFLDdll_TYPE PUREFLDdll; - QMASSdll_TYPE QMASSdll; - QMOLEdll_TYPE QMOLEdll; - SATDdll_TYPE SATDdll; - SATEdll_TYPE SATEdll; - SATHdll_TYPE SATHdll; - SATPdll_TYPE SATPdll; - SATSdll_TYPE SATSdll; - SATTdll_TYPE SATTdll; - SETAGAdll_TYPE SETAGAdll; - SETKTVdll_TYPE SETKTVdll; - SETMIXdll_TYPE SETMIXdll; - SETMODdll_TYPE SETMODdll; - SETREFdll_TYPE SETREFdll; - SETUPdll_TYPE SETUPdll; -// SPECGRdll_TYPE SPECGRdll; // not found in library - SUBLPdll_TYPE SUBLPdll; - SUBLTdll_TYPE SUBLTdll; - SURFTdll_TYPE SURFTdll; - SURTENdll_TYPE SURTENdll; - TDFLSHdll_TYPE TDFLSHdll; - TEFLSHdll_TYPE TEFLSHdll; - THERM0dll_TYPE THERM0dll; - THERM2dll_TYPE THERM2dll; - THERM3dll_TYPE THERM3dll; - THERMdll_TYPE THERMdll; - THFLSHdll_TYPE THFLSHdll; - TPFLSHdll_TYPE TPFLSHdll; - TPFL2dll_TYPE TPFL2dll; - TPRHOdll_TYPE TPRHOdll; - TQFLSHdll_TYPE TQFLSHdll; - TRNPRPdll_TYPE TRNPRPdll; - TSFLSHdll_TYPE TSFLSHdll; - VIRBdll_TYPE VIRBdll; - VIRCdll_TYPE VIRCdll; - WMOLdll_TYPE WMOLdll; - XMASSdll_TYPE XMASSdll; - XMOLEdll_TYPE XMOLEdll; - // - // Define explicit function pointers - typedef RPVersion_TYPE * RPVersion_POINTER; - typedef SETPATHdll_TYPE * SETPATHdll_POINTER; - typedef ABFL1dll_TYPE * ABFL1dll_POINTER; - typedef ABFL2dll_TYPE * ABFL2dll_POINTER; - typedef ACTVYdll_TYPE * ACTVYdll_POINTER; - typedef AGdll_TYPE * AGdll_POINTER; - typedef CCRITdll_TYPE * CCRITdll_POINTER; - typedef CP0dll_TYPE * CP0dll_POINTER; - typedef CRITPdll_TYPE * CRITPdll_POINTER; - typedef CSATKdll_TYPE * CSATKdll_POINTER; - typedef CV2PKdll_TYPE * CV2PKdll_POINTER; - typedef CVCPKdll_TYPE * CVCPKdll_POINTER; - typedef CVCPdll_TYPE * CVCPdll_POINTER; - typedef DBDTdll_TYPE * DBDTdll_POINTER; - typedef DBFL1dll_TYPE * DBFL1dll_POINTER; - typedef DBFL2dll_TYPE * DBFL2dll_POINTER; - typedef DDDPdll_TYPE * DDDPdll_POINTER; - typedef DDDTdll_TYPE * DDDTdll_POINTER; - typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; - typedef DHD1dll_TYPE * DHD1dll_POINTER; - typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; - typedef DHFL1dll_TYPE * DHFL1dll_POINTER; - typedef DHFL2dll_TYPE * DHFL2dll_POINTER; - typedef DIELECdll_TYPE * DIELECdll_POINTER; - typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; - typedef DPDD2dll_TYPE * DPDD2dll_POINTER; - typedef DPDDKdll_TYPE * DPDDKdll_POINTER; - typedef DPDDdll_TYPE * DPDDdll_POINTER; - typedef DPDTKdll_TYPE * DPDTKdll_POINTER; - typedef DPDTdll_TYPE * DPDTdll_POINTER; - typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; - typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; - typedef DSFL1dll_TYPE * DSFL1dll_POINTER; - typedef DSFL2dll_TYPE * DSFL2dll_POINTER; - typedef ENTHALdll_TYPE * ENTHALdll_POINTER; - typedef ENTROdll_TYPE * ENTROdll_POINTER; - typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; - typedef FGCTYdll_TYPE * FGCTYdll_POINTER; - typedef FPVdll_TYPE * FPVdll_POINTER; - typedef GERG04dll_TYPE * GERG04dll_POINTER; - typedef GETFIJdll_TYPE * GETFIJdll_POINTER; - typedef GETKTVdll_TYPE * GETKTVdll_POINTER; - typedef GIBBSdll_TYPE * GIBBSdll_POINTER; - typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; - typedef INFOdll_TYPE * INFOdll_POINTER; - typedef LIMITKdll_TYPE * LIMITKdll_POINTER; - typedef LIMITSdll_TYPE * LIMITSdll_POINTER; - typedef LIMITXdll_TYPE * LIMITXdll_POINTER; - typedef MELTPdll_TYPE * MELTPdll_POINTER; - typedef MELTTdll_TYPE * MELTTdll_POINTER; - typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; - typedef NAMEdll_TYPE * NAMEdll_POINTER; - typedef PDFL1dll_TYPE * PDFL1dll_POINTER; - typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; - typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; - typedef PHFL1dll_TYPE * PHFL1dll_POINTER; - typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; - typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; - typedef PREOSdll_TYPE * PREOSdll_POINTER; - typedef PRESSdll_TYPE * PRESSdll_POINTER; - typedef PSFL1dll_TYPE * PSFL1dll_POINTER; - typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; - typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; - typedef QMASSdll_TYPE * QMASSdll_POINTER; - typedef QMOLEdll_TYPE * QMOLEdll_POINTER; - typedef SATDdll_TYPE * SATDdll_POINTER; - typedef SATEdll_TYPE * SATEdll_POINTER; - typedef SATHdll_TYPE * SATHdll_POINTER; - typedef SATPdll_TYPE * SATPdll_POINTER; - typedef SATSdll_TYPE * SATSdll_POINTER; - typedef SATTdll_TYPE * SATTdll_POINTER; - typedef SETAGAdll_TYPE * SETAGAdll_POINTER; - typedef SETKTVdll_TYPE * SETKTVdll_POINTER; - typedef SETMIXdll_TYPE * SETMIXdll_POINTER; - typedef SETMODdll_TYPE * SETMODdll_POINTER; - typedef SETREFdll_TYPE * SETREFdll_POINTER; - typedef SETUPdll_TYPE * SETUPdll_POINTER; -// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library - typedef SUBLPdll_TYPE * SUBLPdll_POINTER; - typedef SUBLTdll_TYPE * SUBLTdll_POINTER; - typedef SURFTdll_TYPE * SURFTdll_POINTER; - typedef SURTENdll_TYPE * SURTENdll_POINTER; - typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; - typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; - typedef THERM0dll_TYPE * THERM0dll_POINTER; - typedef THERM2dll_TYPE * THERM2dll_POINTER; - typedef THERM3dll_TYPE * THERM3dll_POINTER; - typedef THERMdll_TYPE * THERMdll_POINTER; - typedef THFLSHdll_TYPE * THFLSHdll_POINTER; - typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; - typedef TPFL2dll_TYPE * TPFL2dll_POINTER; - typedef TPRHOdll_TYPE * TPRHOdll_POINTER; - typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; - typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; - typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; - typedef VIRBdll_TYPE * VIRBdll_POINTER; - typedef VIRCdll_TYPE * VIRCdll_POINTER; - typedef WMOLdll_TYPE * WMOLdll_POINTER; - typedef XMASSdll_TYPE * XMASSdll_POINTER; - typedef XMOLEdll_TYPE * XMOLEdll_POINTER; -#ifdef __cplusplus -} // extern "C" -#endif -// REFPROP_H -#endif diff --git a/_wrapper/v0.6/src/refprop_wrapper.cpp b/_wrapper/v0.6/src/refprop_wrapper.cpp deleted file mode 100644 index 4748ee3..0000000 --- a/_wrapper/v0.6/src/refprop_wrapper.cpp +++ /dev/null @@ -1,1870 +0,0 @@ -/* - This is a wrapper file for the Refprop library. It does not include - any functionality besides providing the connection to Refprop. - - The current version was developed by Jorrit Wronski (jowr@mek.dtu.dk) - based on Henning Francke's (francke@gfz-potsdam.de) wrapper. A little - inspiration also came from Ian Bell's (ian.h.bell@gmail.com) wrapper - used in CoolProp - http://coolprop.sourceforge.net/ - - Compatible to the Modelica interface developed by Henning Francke - (francke@gfz-potsdam.de) and his first wrapper class that you can - find in the folder with version 0.5 for Windows systems. -*/ - -/* - * Here are the included files - */ - -#if defined(WIN32) || defined(_WIN32) -#include -#endif - -#include -#include -#include -#include -#include -#include -#include // tolower, toupper, etc - -#include "refprop_lib.h" -//#include -//#include -//#include -//#include - -#include "refprop_wrapper.h" - -// get the POCO classes -#include "Poco/SharedLibrary.h" -#include "Poco/Path.h" -#include "Poco/File.h" -#include "Poco/Environment.h" -#include "Poco/String.h" -#include "Poco/NumberFormatter.h" -#include "Poco/StringTokenizer.h" -#include "Poco/Exception.h" - - -// Define the functions either by their pointers or type. -WMOLdll_POINTER WMOLlib = NULL; -TPFL2dll_POINTER TPFL2lib = NULL; -TPFLSHdll_POINTER TPFLSHlib = NULL; -PHFL1dll_POINTER PHFL1lib = NULL; -PHFLSHdll_POINTER PHFLSHlib = NULL; -PDFL1dll_POINTER PDFL1lib = NULL; -PDFLSHdll_POINTER PDFLSHlib = NULL; -PSFLSHdll_POINTER PSFLSHlib = NULL; -PQFLSHdll_POINTER PQFLSHlib = NULL; -THFLSHdll_POINTER THFLSHlib = NULL; -TDFLSHdll_POINTER TDFLSHlib = NULL; -TSFLSHdll_POINTER TSFLSHlib = NULL; -TQFLSHdll_POINTER TQFLSHlib = NULL; -DHFL1dll_POINTER DHFL1lib = NULL; -DHFL2dll_POINTER DHFL2lib = NULL; -DHFLSHdll_POINTER DHFLSHlib = NULL; -HSFLSHdll_POINTER HSFLSHlib = NULL; -DSFL1dll_POINTER DSFL1lib = NULL; -DSFL2dll_POINTER DSFL2lib = NULL; -DSFLSHdll_POINTER DSFLSHlib = NULL; -TRNPRPdll_POINTER TRNPRPlib = NULL; -SATTdll_POINTER SATTlib = NULL; -SATPdll_POINTER SATPlib = NULL; -SATDdll_POINTER SATDlib = NULL; -SETUPdll_POINTER SETUPlib = NULL; -XMASSdll_POINTER XMASSlib = NULL; -XMOLEdll_POINTER XMOLElib = NULL; - -THERM2dll_POINTER THERM2lib = NULL; -DHD1dll_POINTER DHD1lib = NULL; - - -/* - * Just a helper function control the output of - * an array. Used to debug the handling of the - * composition arrays. - */ -std::string printX(double arr[], long nc) { - std::string ret = "("; - int stop = nc-1; - - for(int i = 0; i < (stop); i++) { - ret = ret + Poco::NumberFormatter::format(arr[i], 4) + ", "; // four decimals - } - - ret = ret + Poco::NumberFormatter::format(arr[stop], 4) + ")"; // four decimals - return ret; -} - - -/* - * Define pointer to library as well as the - * strings we need to determine whether a - * call to SETUPlib is needed. - */ -Poco::SharedLibrary *RefpropdllInstance = NULL; -std::string loadedFluids; - - -/* - * Here we define the fluid's properties. These values get updated after each - * call to Refprop and are used for caching values. I decided to use the - * Refprop units for internal data storage Be careful when converting - * properties using the molecular weight. It is stored in g/mol. - */ - long kq = 2; // all qualities are calculated on a mass basis -static const double noValue = -1e+10; - -static const std::string FLUIDS_PATH = "fluids"; -static const std::string LIN_LIBRARY = "librefprop.so"; -static const std::string WIN_LIBRARY = "refprop.dll"; -Poco::Path FLD_PATH(true); - - -// static const double noFactor = 1e+0; -// static const double presFactor = 1e+3; -// static const double viscFactor = 1e+6; -// static const double molwFactor = 1e-3; -// double energyFactor = noValue; // J/mol / g/mol * 1000g/kg = J/kg -// double densityFactor[3] = {noValue}; // mol/l * g/mol = g/l = kg/m3 for all phases -// double fractionFactor[ncmax] = {noValue}; // xkgi = xmi * mwi * mw (array) -// double qualityFactor = noValue; // qmass = qmole * mw_vap / mw - -bool debug; // set the debug flag -//long lerr; // Error return mechanism -double dhelp = noValue; -//double delta = 1e-20; // tolerance for evaluating differences - - -/* - * Properties for saturation states. "dew" refers to the dew point and - * "bub" describes the bubble point. - */ -double dtdew, dpdew, ddldew, ddvdew, dtbub, dpbub, ddlbub, ddvbub; -int flushSaturation() { - dtdew=noValue; - dpdew=noValue; - ddldew=noValue; - ddvdew=noValue; - dtbub=noValue; - dpbub=noValue; - ddlbub=noValue; - ddvbub=noValue; - if (debug) printf ("Finished flushing saturation properties.\n"); - return 0; -} - - -/* - * Most of the fluid properties are stored here. There are arrays for - * composition information as well as single values for the other - * properties. - * The flush function gets called when the state changes and the - * previously calculated are not valid anymore. A change of state also leads - * to changed saturation conditions. - */ -double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, - ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, - dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, - ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn; - -double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; - -double ddddp_h, ddddh_p; - -int flushProperties(){ - dt=noValue; - dp=noValue; - de=noValue; - dh=noValue; - ds=noValue; - dqmol=noValue; - dd=noValue; - dxmol[0]=noValue; - ddl=noValue; - ddv=noValue; - dxmoll[0]=noValue; - dxmolv[0]=noValue; - dCv=noValue; - dCp=noValue; - dw=noValue; - dwliq=noValue; - dwvap=noValue; - dhjt=noValue; - dZ[0]=noValue; - dA=noValue; - dG=noValue; - dxkappa=noValue; - dbeta=noValue; - ddpdd=noValue; - dd2pdd2=noValue; - ddpdt=noValue; - ddddt=noValue; - ddddp=noValue; - dd2pdt2=noValue; - dd2pdtd=noValue; - ddhdt=noValue; - df=noValue; - deta=noValue; - dtcx=noValue; - dstn=noValue; - - ddhdt_d=noValue; - ddhdt_p=noValue; - ddhdd_t=noValue; - ddhdd_p=noValue; - ddhdp_t=noValue; - ddhdp_d=noValue; - - ddddp_h=noValue; - ddddh_p=noValue; - - if (debug) printf ("Finished flushing normal fluid properties.\n"); - return flushSaturation(); -} - - -/* - * Properties that are constants for pure fluids. Hence, the flushing - * function gets called when a new fluid is loaded. In case of a mixture, - * a change of composition also triggers a flushing since this also - * changes those that also exist for mixtures. - * A change of composition or fluid always leads to a flushing of the - * other properties. - */ -long lnc; // number of components -double dwm, dttp, dtnbp, dtc, dpc, ddc, dZc, dacf, ddip, drgas; -int flushConstants() { - //lnc = -1; - dwm = noValue; - dttp = noValue; - dtnbp = noValue; - dtc = noValue; - dpc = noValue; - ddc = noValue; - dZc = noValue; - dacf = noValue; - ddip = noValue; - drgas = noValue; - if (debug) printf ("Finished flushing fluid/mixture \"constants\".\n"); - return flushProperties(); -} - - -/* - * Make sure that the library is loaded and that all the functions have - * pointers. Perform detailed checks if the debug flag is set. This is - * could be set from inside Modelica to find out why there are problems - * with loading the Refprop library. It is assumed that the library - * file lies in the same directory as the fluid folder. - */ -int setPaths(std::string pathToRefprop, Poco::Path* LP, char* error) { - - if (debug) printf ("\nSetting paths\n"); - - if (pathToRefprop.length()>filepathlength){ - sprintf(error,"Path too long (%i > %i)\n",pathToRefprop.length(),filepathlength); - return -1; - } - - // Parse the string and append a path separator if necessary. - Poco::Path REF_PATH; - REF_PATH.parse(pathToRefprop, Poco::Path::PATH_NATIVE); - if (!REF_PATH.isDirectory()) REF_PATH.append(REF_PATH.separator()); - // Check the path if running in debug mode - if (debug) { - Poco::File refFile(REF_PATH); - if ( !refFile.isDirectory() || !refFile.canRead() ){ - printf ("The provided library path is not a readable directory: %s \n", REF_PATH.toString().c_str()); - sprintf (error,"The provided library path is not a readable directory: %s \n", REF_PATH.toString().c_str()); - return -1; - } else { - printf ("The provided library path is a readable directory: %s \n", REF_PATH.toString().c_str()); - } - } - - // Poco::Path FLD_PATH = (*FP); // get the object - // The fluid files are in the Refprop directory, append "fluids". - FLD_PATH.parse(REF_PATH.toString()); - FLD_PATH.pushDirectory(FLUIDS_PATH); - // Check the path if running in debug mode - if (debug) { - Poco::File fluidFile(FLD_PATH); - if ( !fluidFile.isDirectory() || !fluidFile.canRead() ){ - printf ("The provided fluid path is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - sprintf (error,"The provided fluid path is not a readable directory: %s \n", FLD_PATH.toString().c_str()); - return -1; - } else { - printf ("The provided fluid path is a readable directory: %s \n", FLD_PATH.toString().c_str()); - } - } - - Poco::Path SRC_PATH; // We might want to define the search path differently - bool found_lib; - - // Check the OS and assign the right names for the library - bool is_linux = ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ); - if (is_linux){ - //SRC_PATH.parse("/usr/local/lib"); - SRC_PATH = REF_PATH; - found_lib = Poco::Path::find(SRC_PATH.toString(), LIN_LIBRARY, (*LP)); - } else { - SRC_PATH = REF_PATH; - found_lib = Poco::Path::find(SRC_PATH.toString(), WIN_LIBRARY, (*LP)); - } - - if (found_lib) { - if (debug) printf ("Found library at %s \n", LP->toString().c_str()); - } else { - if (debug) printf ("Cannot find library in path %s \n", SRC_PATH.toString().c_str()); - sprintf (error,"Cannot find library in path %s \n", SRC_PATH.toString().c_str()); - return -1; - } - - // Check the file if running in debug mode - if (debug) { - Poco::File libFile(LP); - if ( !libFile.canRead() ){ - printf ("The provided library is not a readable file: %s \n", LP->toString().c_str()); - sprintf (error,"The provided library is not a readable file: %s \n", LP->toString().c_str()); - return -1; - } else { - printf ("The provided library is a readable file: %s \n", LP->toString().c_str()); - } - } - - return 0; -} - - - -int loadLibrary(std::string pathToRefprop, char* error) { - - if (debug) printf ("\nLoading library.\n"); - - if (RefpropdllInstance==NULL) { - - long lerr = 0; - - if (debug) printf ("Library is not loaded, trying to do so.\n"); - Poco::Path LIB_PATH(true); - - // use the function to set the global path to fluids and - // get the path to the library to load - lerr = setPaths(pathToRefprop, &LIB_PATH, error); - if (lerr!=0) { - printf ("\nThere was an error setting the paths. This hint \n"); - printf ("might help: %s \n", error); - return lerr; - } - - // load a new library instance - if (debug) printf ("Loaded library at: %s \n",LIB_PATH.toString().c_str()); - - RefpropdllInstance = new Poco::SharedLibrary(LIB_PATH.toString()); - if (RefpropdllInstance==NULL) { - printf("Could not load Refprop library, but no error message was provided.\n"); - return -1; - } - - // Get pointers to functions from library. - DHFLSHlib = (DHFLSHdll_POINTER) RefpropdllInstance->getSymbol(DHFLSHdll_NAME); - DSFLSHlib = (DSFLSHdll_POINTER) RefpropdllInstance->getSymbol(DSFLSHdll_NAME); - HSFLSHlib = (HSFLSHdll_POINTER) RefpropdllInstance->getSymbol(HSFLSHdll_NAME); - PDFL1lib = (PDFL1dll_POINTER) RefpropdllInstance->getSymbol(PDFL1dll_NAME); - PDFLSHlib = (PDFLSHdll_POINTER) RefpropdllInstance->getSymbol(PDFLSHdll_NAME); - PHFL1lib = (PHFL1dll_POINTER) RefpropdllInstance->getSymbol(PHFL1dll_NAME); - PHFLSHlib = (PHFLSHdll_POINTER) RefpropdllInstance->getSymbol(PHFLSHdll_NAME); - PQFLSHlib = (PQFLSHdll_POINTER) RefpropdllInstance->getSymbol(PQFLSHdll_NAME); - PSFLSHlib = (PSFLSHdll_POINTER) RefpropdllInstance->getSymbol(PSFLSHdll_NAME); - SATDlib = (SATDdll_POINTER) RefpropdllInstance->getSymbol(SATDdll_NAME); - SATPlib = (SATPdll_POINTER) RefpropdllInstance->getSymbol(SATPdll_NAME); - SATTlib = (SATTdll_POINTER) RefpropdllInstance->getSymbol(SATTdll_NAME); - TDFLSHlib = (TDFLSHdll_POINTER) RefpropdllInstance->getSymbol(TDFLSHdll_NAME); - THFLSHlib = (THFLSHdll_POINTER) RefpropdllInstance->getSymbol(THFLSHdll_NAME); - TPFLSHlib = (TPFLSHdll_POINTER) RefpropdllInstance->getSymbol(TPFLSHdll_NAME); - TQFLSHlib = (TQFLSHdll_POINTER) RefpropdllInstance->getSymbol(TQFLSHdll_NAME); - TRNPRPlib = (TRNPRPdll_POINTER) RefpropdllInstance->getSymbol(TRNPRPdll_NAME); - TSFLSHlib = (TSFLSHdll_POINTER) RefpropdllInstance->getSymbol(TSFLSHdll_NAME); - WMOLlib = (WMOLdll_POINTER) RefpropdllInstance->getSymbol(WMOLdll_NAME); - XMASSlib = (XMASSdll_POINTER) RefpropdllInstance->getSymbol(XMASSdll_NAME); - XMOLElib = (XMOLEdll_POINTER) RefpropdllInstance->getSymbol(XMOLEdll_NAME); - SETUPlib = (SETUPdll_POINTER) RefpropdllInstance->getSymbol(SETUPdll_NAME); - // - THERM2lib = (THERM2dll_POINTER) RefpropdllInstance->getSymbol(THERM2dll_NAME); - DHD1lib = (DHD1dll_POINTER) RefpropdllInstance->getSymbol(DHD1dll_NAME); - - if (debug) printf ("Library instance successfully loaded.\n"); - } else { // library was already loaded - if (debug) printf ("Library instance already loaded, not doing anything.\n"); - } - return 0; -} - - -/* - * Processes the provided strings and constructs a fluid definition string - * that can be digested by the Refprop library. - */ -int setFluid(std::string fluid, char* error){ - - if (debug) printf ("\nSetting fluids\n"); - - char* hf; - char* hfmix; - char* hrf; - std::string RefString; - long lerr; - - // If the name of the fluid doesn't match that of the currently loaded fluid - if (debug) printf("Loaded fluids: %s \n",loadedFluids.c_str()); - if (debug) printf("New fluids: %s \n",fluid.c_str()); - if (loadedFluids.compare(fluid)) { // There is a mismath - if (debug) printf("Loading a new fluid.\n"); - if (fluid.find("|") != std::string::npos) { // check if contains mixture separator - // Created string to insert into parsed fluids - std::string replace = std::string(".FLD|") + FLD_PATH.toString(); - // Prepare final string for values and get tokens - RefString = FLD_PATH.toString(); - Poco::StringTokenizer tokens(std::string(fluid), "|", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); - RefString += Poco::cat(replace, tokens.begin(), tokens.end()); - RefString += std::string(".FLD"); - lnc = tokens.count(); - if (lnc>ncmax){ - sprintf(error,"Too many components (More than %i)\n",ncmax); - return -1; - } - } - else if (!fluid.compare("Air") || !fluid.compare("R507A") || !fluid.compare("R404A") || !fluid.compare("R410A") || !fluid.compare("R407C") || !fluid.compare("SES36")) - { - lnc=1; - RefString = FLD_PATH.toString() + fluid + std::string(".PPF"); - dxmol[0]=1.0; //Pseudo-Pure fluid - } - else - { - lnc=1; - RefString = FLD_PATH.toString() + fluid + std::string(".FLD"); - dxmol[0]=1.0; //Pure fluid - } - - if (debug) printf("RefString: %s \n",RefString.c_str()); - - hf = (char*) calloc(refpropcharlong, sizeof(char)); - hfmix = (char*) calloc(refpropcharlength+8, sizeof(char)); - hrf = (char*) calloc(refpropcharlength, sizeof(char)); - - strcpy(hf,RefString.c_str()); - strcpy(hfmix,FLD_PATH.toString().c_str()); - strcat(hfmix,"HMX.BNC"); - strcpy(hrf,"DEF"); - strcpy(error,"Ok"); - - //...Call SETUPlib to set the fluids - if (debug) { - printf("Running SETUP...\n"); - printf ("No. of components: %li \n", lnc); - printf ("Fluid files: %s \n", RefString.c_str()); - printf ("Mixture file: %s \n", hfmix); - } - - lerr=999; - SETUPlib(lnc, hf, hfmix, hrf, lerr, error); - if (lerr != 0) { - printf("REFPROP setup gives this error during SETUP: %s\n",error); - return lerr; - } - free(hf); - free(hfmix); - free(hrf); - - //Copy the name of the loaded refrigerant back into the temporary holder - loadedFluids = std::string(fluid); - - int flush = flushConstants(); - if (debug) printf("Loading a new fluid, flushing constants: %i.\n",flush); - } else { - if (debug) printf("Fluid was already loaded.\n"); - } - return 0; -} - - -int init_REFPROP(std::string fluidnames, std::string REFPROP_PATH_CHAR, char* errormsg){ -// Sets up the interface to the REFPROP.DLL -// is called by props_REFPROP and satprops_REFPROP -// char DLL_PATH[filepathlength], FLD_PATH[filepathlength]; - - long lerr = 0; - //ierr=0; -// debug = true; - - if (debug) printf ("\nInitialising library\n"); - - lerr = loadLibrary(REFPROP_PATH_CHAR, errormsg); - if (lerr!=0) { - printf ("There was an error loading the library. This hint \n"); - printf ("might help: %s \n", errormsg); - } - -// if (debug) { -// printf ("%s\n"," "); -// printf ("Running OS family : %s \n", Poco::Environment::osName().c_str()); -// printf ("Loaded library : %li \n", lerr); -// printf ("Fluids are located: %s \n", FLD_PATH.toString().c_str()); -// //printf ("%s\n"," "); -// } - - lerr = setFluid(fluidnames, errormsg); - if (lerr!=0) { - printf ("There was an error loading the fluids. This hint \n"); - printf ("might help: %s \n", errormsg); - } - - if (debug) printf("Error code processing...\n"); - switch(lerr){ - case 101: - //strcpy(errormsg,"error in opening file"); -// if (DEBUGMODE) printf("Error 101\n"); - sprintf(errormsg,"error in opening fluid file"); - break; - case 102: -// if (DEBUGMODE) printf("Error 102\n"); - strcpy(errormsg,"error in file or premature end of file"); - break; - case -103: -// if (DEBUGMODE) printf("Error -103\n"); - strcpy(errormsg,"unknown model encountered in file"); - break; - case 104: -// if (DEBUGMODE) printf("Error 104\n"); - strcpy(errormsg,"error in setup of model"); - break; - case 105: -// if (DEBUGMODE) printf("Error 105\n"); - strcpy(errormsg,"specified model not found"); - break; - case 111: -// if (DEBUGMODE) printf("Error 111\n"); - strcpy(errormsg,"error in opening mixture file"); - break; - case 112: -// if (DEBUGMODE) printf("Error 112\n"); - strcpy(errormsg,"mixture file of wrong type"); - break; - case 114: -// if (DEBUGMODE) printf("Error 114\n"); - strcpy(errormsg,"nc<>nc from setmod"); - break; - case 0: - break; - default: -// if (DEBUGMODE) printf("Unknown error\n"); - sprintf(errormsg,"There was an unknown error(%li): %s",lerr,errormsg); - // strcpy(errormsg,"Unknown error"); - //strcpy(errormsg,"Setup was successful!"); - // strncpy(errormsg,herr,errormessagelength); - break; - } - return lerr; -} - -bool isInput(std::string in1, std::string in2, std::string def){ - // if the first equals the first - if ( 0 == Poco::icompare(in1, def.substr(0,1)) ) { - if ( 0 == Poco::icompare(in2, def.substr(1,1)) ) return true; - } else if ( 0 == Poco::icompare(in2, def.substr(0,1)) ) { - if ( 0 == Poco::icompare(in1, def.substr(1,1)) ) return true; - } - return false; -} - -double getT_refprop(double t) { - // t--temperature [K] - return t*1.; -} - -double getP_refprop(double p) { - // p--pressure [kPa] - return p/1000.0; -} - -double getD_refprop(double d) { - // d--bulk molar density [mol/L] - return d/dwm; // kg/m3 = g/l / g/mol = mol/l -} - -double getE_refprop(double e) { - // e--internal energy [J/mol] - return e*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol -} - -double getH_refprop(double h) { - // h--enthalpy [J/mol] - return h*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol -} - -double getS_refprop(double s) { - // s--entropy [[J/mol-K] - return s*dwm/1000.; // J/(kg.K) * g/mol * kg/(1000g) = J/(mol.K) -} - -/* - * Convert to SI units - */ -double getT_modelica() { - // t--temperature [K] - return dt; -} - -double getP_modelica() { - // p--pressure [kPa] - return dp*1000.0; -} - -double getD_modelica() { - // d--bulk molar density [mol/L] - return dd*dwm; // mol/l * g/mol = g/l = kg/m3 -} - -double getE_modelica() { - // e--internal energy [J/mol] - return de/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg -} - -double getH_modelica() { - // h--enthalpy [J/mol] - return dh/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg -} - -double getS_modelica() { - // s--entropy [[J/mol-K] - return ds/dwm * 1000.0; // J/(mol.K) / g/mol * 1000g/kg = J/(kg.K) -} - -double getWM_modelica(){ - //molecular weight - return dwm/1000; -} - -double getDL_modelica(){ - //density of liquid phase - return ddl*dwliq; // mol/l * g/mol = g/l = kg/m3 -} - -double getDV_modelica(){ - //density of gaseous phase - return ddv*dwvap; // mol/l * g/mol = g/l = kg/m3 -} - -double getQ_modelica(){ - if (lnc>1 && abs(dqmol)<990) { // maintain special values - if (dwvap==noValue) WMOLlib(dxmolv,dwvap); - return dqmol*dwvap/dwm; - } else { - return dqmol; - } -} - -double getCV_modelica(){ - return dCv/dwm * 1000.0; -} - -double getCP_modelica(){ - return dCp/dwm * 1000.0; -} - -double getW_modelica(){ - //speed of sound - return dw; -} - -double getWML_modelica(){ - if (dwliq==noValue) WMOLlib(dxmoll,dwliq); - return dwliq/1000.; -} - -double getWMV_modelica(){ - if (dwvap==noValue) WMOLlib(dxmolv,dwvap); - return dwvap/1000.; -} - -//double* getXL_modelica(){ -// double dxlkg[ncmax]; -// XMASSlib(dxmoll,dxlkg,dwliq); -// return dxlkg; -//} -// -//double* getXV_modelica(){ -// double dxvkg[ncmax]; -// XMASSlib(dxmolv,dxvkg,dwvap); -// return dxvkg; -//} - -double getETA_modelica(){ - return deta/1e6; -} - -double getTCX_modelica(){ - return dtcx; -} - -double getHJT_modelica() { // isenthalpic Joule-Thompson coefficient [K/kPa]/1000Pa*kPa = K/Pa - return dhjt/1000; -} -//double* getZ_modelica() { // compressibility factor (= PV/RT) [dimensionless] -// return dZ; -//} -double getA_modelica() { // Helmholtz energy [J/mol] - return dA/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg -} -double getG_modelica() { // Gibbs free energy [J/mol] - return dG/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg -} -double getXKAPPA_modelica() { // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/kPa] /1000Pa*kPa = 1/Pa - return dxkappa / 1000. ; -} -double getBETA_modelica() { // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] - return dbeta; -} -double getDPDD_modelica() { // derivative dP/drho [kPa-L/mol] * 1000Pa/kPa * mol/g = Pa.m3 / kg - return ddpdd * 1000. / dwm; -} -double getD2PDD2_modelica() { // derivative d^2P/drho^2 [kPa-L^2/mol^2] * 1000Pa/kPa * mol/g * mol/g = Pa m6 / kg2 - return dd2pdd2 * 1000. / dwm / dwm; -} -double getDPDT_modelica() { // derivative dP/dT [kPa/K] * 1000Pa/kPa = Pa/K - return ddpdt * 1000.; -} -double getDDDT_modelica() { // derivative drho/dT [mol/(L-K)] * g/mol = kg/m3 / K - return ddddt * dwm; -} -double getDDDP_modelica() { // derivative drho/dP [mol/(L-kPa)] - return ddddp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) -} -double getD2PDT2_modelica() { // derivative d2P/dT2 [kPa/K^2] * 1000Pa/kPa = Pa/K2 - return dd2pdt2 * 1000.; -} -double getD2PDTD_modelica() { // derivative d2P/dTd(rho) [J/mol-K] / g/mol * 1000g/kg = J/kg.K - return dd2pdtd/dwm*1000.; -} - - -double get_dhdt_d_modelica() { //dH/dT at constant density [J/(mol-K)] / g/mol * 1000g/kg = J/kg.K - return ddhdt_d/dwm*1000; -} -double get_dhdt_p_modelica() { //dH/dT at constant pressure [J/(mol-K)] - return ddhdt_p/dwm*1000; -} -double get_dhdd_t_modelica() { //dH/drho at constant temperature [(J/mol)/(mol/L)] * mol/g * 1000g/kg / g/mol = (J/kg) / (kg/m3) - return ddhdd_t /dwm*1000. / dwm; -} -double get_dhdd_p_modelica() { //dH/drho at constant pressure [(J/mol)/(mol/L)] - return ddhdd_p /dwm*1000. / dwm; -} -double get_dhdp_t_modelica() { //dH/dP at constant temperature [J/(mol-kPa)] /dwm*1000. / (1000Pa/kPa) = J/kg.Pa - return ddhdp_t / dwm; -} -double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] - return ddhdp_d / dwm; -} - -// Numerical derivatives -// Derivative of density with respect to enthalpy at constant pressure -double get_dddh_p_modelica(){ - return ddddh_p*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J -} -// Derivative of density with respect to pressure at constant enthalpy -double get_dddp_h_modelica(){ - return ddddp_h*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) -} - - -/* - * Checks if the provided variables match the currently active - * state. Needs the current values of the state properties as - * well as the new ones. Additionally, the mole based composition - * has to be provided with the number of components. - * Changing the amount of components or the fluids itself should - * be covered by the flushing routines above. - */ -bool isState(double var1, double val1, double var2, double val2, double xmol[], long nc){ - if (debug) printf ("\nChecking state.\n"); - if (var1!=val1) return false; - if (var2!=val2) return false; - //if (lnc!=nc) return false; - // If we have a mixture, we need to check the composition. - if (nc>1) { - for ( int i = 0; i < nc; i++ ) { - if (dxmol[i]!=xmol[i]) return false; - } - } - if (debug) printf ("Going to return \"true\".\n"); - return true; -} - - -double getValue(std::string out) { - - if (debug) printf("\nChecking for %s \n",out.c_str()); - - if ( 0 == Poco::icompare(out, "p") ) { - if (dp!=noValue) return getP_modelica(); - } else if ( 0 == Poco::icompare(out, "t") ) { - if (dt!=noValue) return getT_modelica(); - } else if ( 0 == Poco::icompare(out, "m") ) { - if (dwm!=noValue) return getWM_modelica(); - } else if ( 0 == Poco::icompare(out, "d") ) { - if (dd!=noValue) return getD_modelica(); - } else if ( 0 == Poco::icompare(out, "e") ) { - if (de!=noValue) return getE_modelica(); - } else if ( 0 == Poco::icompare(out, "h") ) { - if (dh!=noValue) return getH_modelica(); - } else if ( 0 == Poco::icompare(out, "s") ) { - if (ds!=noValue) return getS_modelica(); - } else if ( 0 == Poco::icompare(out, "w") ) { - if (dw!=noValue) return getW_modelica(); - } else if ( 0 == Poco::icompare(out, "v") ) { - if (deta!=noValue) return getETA_modelica(); - } else if ( 0 == Poco::icompare(out, "l") ) { - if (dtcx!=noValue) return getTCX_modelica(); - } - return noValue; -} - -///* -// * Improvised derivative computing. These functions are called -// * after properties were calculated. Hence, we have density and -// * pressure available. REFPROP is formulated with explicit d and -// * T it should not take too much extra time. -// */ -//double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; -//double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; -//int setExtra(bool debug, long lerr, char* errormsg){ -// double rho,T; -// rho = getValue("d"); -// T = getValue("T"); -// if ((rho!=noValue)&&(T!=noValue)) { // call explicit function -// // get derivative of density with respect to pressure from Refprop library -// if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); -// THERM2lib (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); -//// deltaP = 1.; -//// pLow = dp - 0.5*deltaP; -//// pHigh = dp + 0.5*deltaP; -//// rhoLow = 0; -//// rhoHigh = 0; -//// //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); -//// PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); -//// PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -//// if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); -//// ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); -// -// // get derivative of density with respect to enthalpy numerically -// deltaH = 20.; -// hLow = dh - 0.5*deltaH; -// hHigh = dh + 0.5*deltaH; -// rhoLow = 0; -// rhoHigh = 0; -// //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); -// PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); -// PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -// if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); -// ddddh = (rhoHigh-rhoLow) / (hHigh-hLow); -// } else { // We have a problem! -// printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); -// } -// return 0; -//} - -//int updateExtra(double *der, long lerr){ -//// c inputs: -//// c t--temperature [K] -//// c rho--molar density [mol/L] -//// c x--composition [array of mol frac] -//// c outputs: -//// c p--pressure [kPa] -//// c e--internal energy [J/mol] -//// c h--enthalpy [J/mol] -//// c s--entropy [J/mol-K] -//// c Cv--isochoric heat capacity [J/mol-K] -//// c Cp--isobaric heat capacity [J/mol-K] -//// c w--speed of sound [m/s] -//// c Z -//// c hjt -//// c A -//// c G -//// c xkappa -//// c beta -//// c dPdrho -//// c d2PdD2 -//// c dPT -//// c drhodT -//// c drhodP -//// c d2PT2 -//// c d2PdTD -//// c sparei--2 space holders for possible future properties -// -// -//// subroutine DHD1(t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d) -////c -////c compute partial derivatives of enthalpy w.r.t. t, p, or rho at constant -////c t, p, or rho as a function of temperature, density, and composition -////c -////c inputs: -////c t--temperature [K] -////c rho--molar density [mol/L] -////c x--composition [array of mol frac] -////c outputs: -////c get_dhdt_d_modelica(); --dH/dT at constant density [J/(mol-K)] -////c get_dhdt_p_modelica(); --dH/dT at constant pressure [J/(mol-K)] -////c get_dhdd_t_modelica(); --dH/drho at constant temperature [(J/mol)/(mol/L)] -////c get_dhdd_p_modelica(); --dH/drho at constant pressure [(J/mol)/(mol/L)] -////c get_dhdp_t_modelica(); --dH/dP at constant temperature [J/(mol-kPa)] -////c get_dhdp_d_modelica(); --dH/dP at constant density [J/(mol-kPa)] -// -//// double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, -//// ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, -//// - - -// -// -// -// -// getDDDH -// -// -// -// -//// THERM2lib (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); -// -// //ASSIGN VALUES TO RETURN ARRAY -// der[0] = lerr;//error code -// der[1] = getP_modelica(); //pressure in Pa -// der[2] = getT_modelica(); //Temperature in K -// der[3] = getWM_modelica(); //molecular weight -// der[4] = getD_modelica(); //density -// der[5] = getDL_modelica(); //density of liquid phase -// der[6] = getDV_modelica(); //density of liquid phase -// der[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) -// der[8] = getE_modelica(); //internal energy -// der[9] = getH_modelica(); //specific enthalpy -// der[10] = getS_modelica(); //specific entropy -// der[11] = getCV_modelica(); // heat capacity -// der[12] = getCP_modelica(); // heat capacity -// der[13] = getW_modelica(); //speed of sound -// der[14] = getDDDH_modelica(); //ddhp -// der[15] = getDDDP_modelica(); //ddph -// der[16] = getWML_modelica(); -// der[17] = getWMV_modelica(); -// -// double dxlkg[ncmax], dxvkg[ncmax]; -// -// -// return 0; -//} - - - -int updateDers(double *ders, long lerr){ - //ASSIGN VALUES TO RETURN ARRAY - ders[0] = lerr;//error code - ders[1] = getHJT_modelica(); // isenthalpic Joule-Thompson coefficient [K/Pa] - ders[2] = getA_modelica(); // Helmholtz energy [J/kg] - ders[3] = getG_modelica(); // Gibbs free energy [J/kg] - ders[4] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] - ders[5] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] - ders[6] = getDPDD_modelica(); // derivative dP/drho [Pa-m3/kg] - ders[7] = getD2PDD2_modelica(); // derivative d^2P/drho^2 [Pa-m6/kg2] - ders[8] = getDPDT_modelica(); // derivative dP/dT [Pa/K] - ders[9] = getDDDT_modelica(); // derivative drho/dT [kg/(m3-K)] - ders[10] = getDDDP_modelica(); // derivative drho/dP [kg/(m3-kPa)] - ders[11] = getD2PDT2_modelica(); // derivative d2P/dT2 [Pa/K2] - ders[12] = getD2PDTD_modelica(); // derivative d2P/dTd(rho) [J/kg-K] - ders[13] = get_dhdt_d_modelica(); // dH/dT at constant density [J/(kg-K)] - ders[14] = get_dhdt_p_modelica(); // dH/dT at constant pressure [J/(kg-K)] - ders[15] = get_dhdd_t_modelica(); // dH/drho at constant temperature [(J/kg) / (kg/m3)] - ders[16] = get_dhdd_p_modelica(); // dH/drho at constant pressure [(J/kg) / (kg/m3)] - ders[17] = get_dhdp_t_modelica(); // dH/dP at constant temperature [J/(kg-Pa)] - ders[18] = get_dhdp_d_modelica(); // dH/dP at constant density [J/(kg-Pa)] - ders[19] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] - ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] - return 0; -} - -int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ - debug = false; - if (DEBUGMODE) debug = true; - long lerr = 0; - - double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; - double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; - - if ((dd!=noValue)&&(dt!=noValue)) { - // call explicit functions in d and T - // get derivatives from Refprop library - if (debug) printf("Calling THERM2 with T=%f and rho=%f.\n",dt,dd); - THERM2lib (dt,dd,dxmol,spare5,spare6,spare9,spare10,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); - - // get derivatives of enthalpy - if (debug) printf("Calling DHD1 with T=%f and rho=%f.\n",dt,dd); - DHD1lib(dt,dd,dxmol,ddhdt_d,ddhdt_p,ddhdd_t,ddhdd_p,ddhdp_t,ddhdp_d); - - /* - * With the above values, the cyclic relation can be used to - * determine all necessary values. - * - * -1 = ddddp_ana * 1/(props.state.dhdp_rho) * props.state.dhdrho_p; - * ddddh_ana * props.state.dhdrho_p= 1; - * - * Below is a numerical approximation due to problems in the - * two-phase region. - */ - - if (dqmol < 0. || dqmol > 1.) { // single-phase region - if (debug) printf ("Using single-phase derivatives.\n"); - ddddp_h = -1. * ddhdp_d / ddhdd_p; - ddddh_p = 1./ddhdd_p; - } else { // two-phase region, get derivative of density with respect to enthalpy numerically - if (debug) printf ("Using two-phase derivatives.\n"); - deltaP = 0.00005; // 0.05 Pascal difference - pLow = dp - 0.5*deltaP; - pHigh = dp + 0.5*deltaP; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); - PHFLSHlib(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); - PHFLSHlib(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); - ddddp_h = (rhoHigh-rhoLow) / (pHigh-pLow); - - // get derivative of density with respect to enthalpy numerically - deltaH = 0.05; // 0.05 Joule total difference - hLow = dh - 0.5*deltaH; - hHigh = dh + 0.5*deltaH; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHlib(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); - PHFLSHlib(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); - PHFLSHlib(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); - ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); - } - - } else { // We have a problem! - printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); - } - - switch(lerr){ - case 4: - sprintf(errormsg,"P=%f < 0",dp); - break; - case 8: - sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); - break; - case 12: - sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); - break; - default: - break; - } - return updateDers(ders, lerr); -} - -int updateTrns(double *trns, long lerr){ - //ASSIGN VALUES TO RETURN ARRAY - trns[0] = lerr;//error code - trns[1] = getETA_modelica(); // dynamic viscosity in Pa.s - trns[2] = getTCX_modelica(); // thermal conductivity in W/m.K - return 0; -} - -int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ - debug = false; - if (DEBUGMODE) debug = true; - long lerr = 0; - - if ((dd!=noValue)&&(dt!=noValue)) { - // call explicit functions in d and T - // compute transport properties - if (debug) printf("Getting transport properties from T=%f and rho=%f.\n",dt,dd); - TRNPRPlib(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); - if (debug) printf("Thermal conductivity is lambda=%f W/m.K.\n",dtcx); - if (debug) printf("Dynamic viscosity is eta=%fµPa.s.\n",deta); - - } else { // We have a problem! - printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); - } - - switch(lerr){ - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",dd); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",dd); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - default: - break; - } - return updateTrns(trns, lerr); -} - - -int updateProps(double *props, long lerr){ - //ASSIGN VALUES TO RETURN ARRAY - props[0] = lerr;//error code - props[1] = getP_modelica(); //pressure in Pa - props[2] = getT_modelica(); //Temperature in K - props[3] = getWM_modelica(); //molecular weight - props[4] = getD_modelica(); //density - props[5] = getDL_modelica(); //density of liquid phase - props[6] = getDV_modelica(); //density of liquid phase - props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) - props[8] = getE_modelica(); //inner energy - props[9] = getH_modelica(); //specific enthalpy - props[10] = getS_modelica(); //specific entropy - props[11] = getCV_modelica(); - props[12] = getCP_modelica(); - props[13] = getW_modelica(); //speed of sound - props[14] = getWML_modelica(); - props[15] = getWMV_modelica(); - - double dxlkg[ncmax], dxvkg[ncmax]; - - XMASSlib(dxmoll,dxlkg,dwliq); - XMASSlib(dxmolv,dxvkg,dwvap); - - for (int dim=0; dim1) flushConstants(); - else flushProperties(); - if (debug) printf("Loading a new state, flushed state. \n"); - } else { // We have calculated it before. - if (valueExists) { - if (debug) printf("Working with old state, returning value for %s: %f.\n",out.c_str(),result); - updateProps(props, lerr); - return result; - } - } - - - /* - * If we get to this point, the requested value was not part of an earlier - * calculation and we have to proceed to determine it via the Refprop library. - */ - // ( 0 == Poco::icompare(Poco::Environment::osName(), "linux") ) - - // Set variables to input values - if ( 0 == Poco::icompare(in1, in2) ) { - sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return -1; - } - - memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; - //dxmol = dxmoltmp; - dwm = dwmtmp; - - double dqkg; - for (int ii=1;ii<3;ii++){ - - if (ii==1) { - tmpVar = in1; - tmpValue = statevar1; - } else if (ii==2) { - tmpVar = in2; - tmpValue = statevar2; - } - - // loop through possible inputs - if ( 0 == Poco::icompare(tmpVar, "p") ) { - dp = getP_refprop(tmpValue); - } else if ( 0 == Poco::icompare(tmpVar, "T") ) { - dt = getT_refprop(tmpValue); - } else if ( 0 == Poco::icompare(tmpVar, "s") ) { - ds = getS_refprop(tmpValue); - } else if ( 0 == Poco::icompare(tmpVar, "h") ) { - dh = getH_refprop(tmpValue); - } else if ( 0 == Poco::icompare(tmpVar, "d") ) { - dd = getD_refprop(tmpValue); - } else if ( 0 == Poco::icompare(tmpVar, "q") ) { - dqkg = tmpValue; - } else { - lerr = 2; - sprintf(errormsg,"Unknown state variable %i: %s",ii ,tmpVar.c_str()); - return lerr; - } - - if (debug) printf("Checked input variable: %s\n",tmpVar.c_str()); - } - - if (lerr==0){ - if (isInput(in1,in2,std::string("tp"))){ -// if (phase==2){ //fluid state is known to be two phase -// TPFL2lib(dt,dp,dxmol,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); -// }else{ - if (debug) printf("Calling TPFLSH with %f and %f.\n",dt,dp); - TPFLSHlib(dt,dp,dxmol,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - //if (debug) printf("Getting dd: %f\n",dd); -// } - }else if (isInput(in1,in2,std::string("ph"))){ -// if (phase==1){ //fluid state is known to be single phase -// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); -//// if (liqvap==1) dl=d; else dv=d; -// }else{ - if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,dh); - PHFLSHlib(dp,dh,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// } - }else if (isInput(in1,in2,std::string("pd"))){ - if (phase==1){ //fluid state is known to be single phase - PDFL1lib(dp,dd,dxmol,dt,lerr,errormsg,errormessagelength); - }else{ - if (debug) printf("Calling PDFLSH with %f and %f.\n",dp,dd); - PDFLSHlib(dp,dd,dxmol,dt,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - } - }else if (isInput(in1,in2,std::string("sp"))){ -/* if (phase==1){ //fluid state is known to be single phase - PSFL1(p,s,dxmol,kph,T,d,lerr,errormsg,errormessagelength); - if (liqvap==1) dl=d; else dv=d; - }else{*/ - if (debug) printf("Calling PSFLSH with %f and %f.\n",dp,ds); - PSFLSHlib(dp,ds,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// } - }else if (isInput(in1,in2,std::string("pq"))){ - if (debug) printf("Calling PQFLSH with %f and %f.\n",dp,dqkg); - PQFLSHlib(dp,dqkg,dxmol,kq,dt,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// strcat(errormsg,"Bin in PQ!"); - }else if (isInput(in1,in2,std::string("th"))){ -/* if (phase==1){ //fluid state is known to be single phase - THFL1(T,h,dxmol,Dmin,Dmax,d,lerr,errormsg,errormessagelength); - }else{*/ - long kr = 2; -/* kr--phase flag: 1 = input state is liquid - 2 = input state is vapor in equilibrium with liq - 3 = input state is liquid in equilibrium with solid - 4 = input state is vapor in equilibrium with solid */ - if (debug) printf("Calling THFLSH with %f and %f.\n",dt,dh); - THFLSHlib(dt,dh,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// } - }else if (isInput(in1,in2,std::string("td"))){ - if (debug) printf("Calling TDFLSH with %f and %f.\n",dt,dd); - TDFLSHlib(dt,dd,dxmol,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - }else if (isInput(in1,in2,std::string("ts"))){ - long kr = 2; - if (debug) printf("Calling TSFLSH with %f and %f.\n",dt,ds); - TSFLSHlib(dt,ds,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); - }else if (isInput(in1,in2,std::string("tq"))){ - if (debug) printf("Calling TQFLSH with %f and %f.\n",dt,dqkg); - TQFLSHlib(dt,dqkg,dxmol,kq,dp,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - }else if (isInput(in1,in2,std::string("dh"))){ - switch(phase){ //fluid state is known to be single phase - case 1: - DHFL1lib(dd,dh,dxmol,dt,lerr,errormsg,errormessagelength); - break; - case 2: - DHFL2lib(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); - break; - default: - if (debug) printf("Calling DHFLSH with %f and %f.\n",dd,dh); - DHFLSHlib(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - break; - } - }else if (isInput(in1,in2,std::string("hs"))){ - HSFLSHlib(dh,ds,dxmol,dt,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dCv,dCp,dw,lerr,errormsg,errormessagelength); - }else if (isInput(in1,in2,std::string("ds"))){ - switch(phase){ //fluid state is known to be single phase - case 1: - DSFL1lib(dd,ds,dxmol,dt,lerr,errormsg,errormessagelength); - break; - case 2: - DSFL2lib(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); - break; - default: - if (debug) printf("Calling DSFLSH with %f and %f.\n",dd,ds); - DSFLSHlib(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); - break; - } - }else - sprintf(errormsg,"Unknown combination of state variables! %s and %s", in1.c_str(), in2.c_str()); - } - - -// switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE -// case 'v': //dynamic viscosity uPa.s -// case 'l': //thermal conductivity W/m.K -// TRNPRPlib(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); -// break; -// } - - - switch(lerr){ - case 1: - sprintf(errormsg,"T=%f < Tmin",dt); - break; - case 4: - sprintf(errormsg,"P=%f < 0",dp); - break; - case 5: - sprintf(errormsg,"T=%f and p=%f out of range",dt,dp); - break; - case 8: - sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); - break; - case 9: - sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); - break; - case 12: - sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); - break; - case 13: - sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); - break; - case 16: - strcpy(errormsg,"TPFLSH error: p>melting pressure"); - break; - case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); - break; - case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",dd); - break; - case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); - break; - case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); - break; - case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",dd); - break; - case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); - break; - case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); - break; - case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); - break; - case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); - break; - case 39: - sprintf(errormsg,"model not found for thermal conductivity"); - break; - case 49: - sprintf(errormsg,"model not found for viscosity"); - break; - case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); - break; - case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); - break; - case -58: - case -59: - sprintf(errormsg,"ECS model did not converge"); - break; - case 211: - sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); - break; - case 239: - sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); - break; - case 248: - sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); - break; - case 249: - sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); - break; - case 271: - sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); - break; - case 291: - sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); - break; - default: - //strncpy(errormsg,errormsg,errormessagelength); - break; - } - - - updateProps(props, lerr); - - int outVal = ders_REFPROP(ders,errormsg,debug); - if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - - outVal = trns_REFPROP(trns,errormsg,debug); - if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - - - if ( 0 == Poco::icompare(out, "p") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); - return getP_modelica(); - } else if ( 0 == Poco::icompare(out, "t") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getT_modelica()); - return getT_modelica(); - } else if ( 0 == Poco::icompare(out, "m") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getWML_modelica()); - return getWM_modelica(); - } else if ( 0 == Poco::icompare(out, "d") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getD_modelica()); - return getD_modelica(); - } else if ( 0 == Poco::icompare(out, "q") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getQ_modelica()); - return getQ_modelica(); - } else if ( 0 == Poco::icompare(out, "e") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getE_modelica()); - return getE_modelica(); - } else if ( 0 == Poco::icompare(out, "h") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getH_modelica()); - return getH_modelica(); - } else if ( 0 == Poco::icompare(out, "s") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getS_modelica()); - return getS_modelica(); - } else if ( 0 == Poco::icompare(out, "w") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getW_modelica()); - return getW_modelica(); - } else if ( 0 == Poco::icompare(out, "v") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getETA_modelica()); - return getETA_modelica(); - } else if ( 0 == Poco::icompare(out, "l") ) { - if (debug) printf("Returning %s = %f\n",out.c_str(),getTCX_modelica()); - return getTCX_modelica(); - } else { - return -1.0; - } - -} - - -//--------------------------------------------------------------------------- - - -double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ -/*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) -INPUT: - what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function - statevar: string of 1 variable out of p,T,h,s,d - fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory - statevarval: values of the variable specified in statevar - x: array containing the mass fractions of the components of the mixture - REFPROP_PATH: string defining the path of the refprop.dll -OUTPUT - return value: value of variable specified by the input variable what - props: Array containing all calculated values - errormsg: string containing error message -*/ - - - long lerr = 0; - - -// DEBUGMODE = 1; - if (DEBUGMODE) debug = true; - std::string out = std::string(what).substr(0,1); - std::string in1 = std::string(statevar_in).substr(0,1); - std::string fluids = std::string(fluidnames); - std::string rPath = std::string(REFPROP_PATH); - - - /* - * Call method to initialise the library and check for new fluids. - * Afterwards, the fluids have been processed and the constants might - * have been flushed. - */ - if (debug) printf("\nStarting function satprops_REFPROP to calculate %s.\n", out.c_str()); - - lerr = init_REFPROP(fluids, rPath, errormsg); - - if (lerr!=0) { - printf("Error no. %li initialising REFPROP: \"%s\"\n", lerr, errormsg); - return lerr; - } - - - /* - * Here should be the state checking to avoid unnecessary calculations. when - * working with mixtures, the constants also have to be flushed if the - * composition changes. - */ - bool knownState = false; // dummies to force recalculation - bool valueExists = false; - - if (!knownState) { - if (lnc>1) flushConstants(); - else flushProperties(); - if (debug) printf("Loading a new state, flushed state. \n"); - } else { // We have calculated it before. - if (valueExists) { - if (debug) printf("Working with old state, returning value for %i: %f.\n",what[0],-1.0); - return -1.0; - } - } - - - /* - * If we get to this point, the requested value was not part of an earlier - * calculation and we have to proceed to determine it via the Refprop library. - */ - - // Convert mass-based composition to mole fractions and set molecular weight. - double* dxkg; - dxkg = x; - XMOLElib(dxkg,dxmol,dwm); - // dwm = dwm / 1000; // from g/mol to kg/mol - - // loop through possible inputs - if ( 0 == Poco::icompare(in1, "p") ) { - dp = getP_refprop(statevarval); - } else if ( 0 == Poco::icompare(in1, "t") ) { - dt = getT_refprop(statevarval); - } else if ( 0 == Poco::icompare(in1, "d") ) { - dd = getD_refprop(statevarval); - } else { - lerr = 2; - sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); - return lerr; - } - if (debug) printf("\nstatevar %s checked\n",in1.c_str()); - - long j=2; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - long kph = -1; -/* kph--flag specifying desired root for multi-valued inputs - has meaning only for water at temperatures close to its triple point - -1 = return middle root (between 0 and 4 C) - 1 = return highest temperature root (above 4 C) - 3 = return lowest temperature root (along freezing line) */ - if (lerr==0) { - if ( 0 == Poco::icompare(in1, "t") ) { - SATTlib(dt,dxmol,j,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); - } else if ( 0 == Poco::icompare(in1, "p") ) { - SATPlib(dp,dxmol,j,dt,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); - switch(lerr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; - } - //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - } else if ( 0 == Poco::icompare(in1, "d") ) { - SATDlib(dd,dxmol,j,kph,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); - switch(lerr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - } - - switch(lerr){ - case 0: - strcpy(errormsg,"Saturation routine successful"); - break; - case 1: - sprintf(errormsg,"T=%f < Tmin",dt); - break; - case 8: - sprintf(errormsg,"x out of range, %s",printX(dxmol,lnc).c_str()); - break; - case 9: - sprintf(errormsg,"T=%f and x=%s out of range",dt,printX(dxmol,lnc).c_str()); - break; - case 10: - strcpy(errormsg,"D and x out of range"); - break; - case 12: - strcpy(errormsg,"P and x out of range"); - break; - case 120: - strcpy(errormsg,"CRITP did not converge"); - break; - case 121: - strcpy(errormsg,"T > Tcrit"); - break; - case 122: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 123: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 124: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -125: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -126: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -127: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 128: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 140: - strcpy(errormsg,"CRITP did not converge"); - break; - case 141: - strcpy(errormsg,"P > Pcrit"); - break; - case 142: - strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); - break; - case 143: - strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); - break; - case 144: - strcpy(errormsg,"pure fluid iteration did not converge"); - break; - case -144: - strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); - break; - case -145: - strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); - break; - case -146: - strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); - break; - case -147: - strcpy(errormsg,"composition iteration did not converge"); - break; - case 148: - strcpy(errormsg,"mixture iteration did not converge"); - break; - case 160: - strcpy(errormsg,"CRITP did not converge"); - break; - case 161: - strcpy(errormsg,"SATD did not converge"); - break; - default: - //strncpy(errormsg,herr,errormessagelength); - break; - } - - //ASSIGN VALUES TO RETURN ARRAY - props[0] = lerr;//error code - props[1] = getP_modelica(); //pressure in kPa->Pa - props[2] = getT_modelica(); //Temperature in K - props[3] = getWM_modelica(); //molecular weight - props[4] = getD_modelica(); //density - props[5] = getDL_modelica(); //density of liquid phase - props[6] = getDV_modelica(); //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0; //specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = getWML_modelica(); - props[15] = getWMV_modelica(); - - double dxlkg[ncmax], dxvkg[ncmax]; - - XMASSlib(dxmoll,dxlkg,dwliq); - XMASSlib(dxmolv,dxvkg,dwvap); - - for (int ii=0;ii -#include -#include -#include "refprop_wrapper.h" - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -int main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255+1024]; - double* x; - double *props; - double *ders; - double *trns; - double sumx; - int i; - int nX = argc-5; - int DEBUG = 1; - - if (argc<5){ -// printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); - printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); - return 1; - } - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - ders=(double*) calloc(21,sizeof(double)); - trns=(double*) calloc(3,sizeof(double)); - - - sumx = 0; - for (i=0;i Date: Wed, 24 Jul 2013 20:05:08 +0200 Subject: [PATCH 28/57] Added code for Windows, should run now Included an ammonia/water example for thomas and anish compiling from source is now default setting --- Examples.mo | 13 - Interfaces/PartialMixtureTwoPhaseMedium.mo | 13 +- Interfaces/package.order | 4 +- Testers/PropsMixtureNH3H2O.mo | 32 + Testers/package.order | 5 +- _wrapper/Makefile | 178 ++ _wrapper/Makefile.bat | 28 + _wrapper/bin/refprop_library.h | 788 +++++++ _wrapper/src/refprop_library.h | 788 +++++++ _wrapper/src/refprop_wrapper.cpp | 2205 ++++++++++++++++++++ _wrapper/src/refprop_wrapper.h | 50 + package.mo | 6 +- package.order | 2 +- 13 files changed, 4082 insertions(+), 30 deletions(-) create mode 100644 Testers/PropsMixtureNH3H2O.mo create mode 100644 _wrapper/Makefile create mode 100644 _wrapper/Makefile.bat create mode 100644 _wrapper/bin/refprop_library.h create mode 100644 _wrapper/src/refprop_library.h create mode 100644 _wrapper/src/refprop_wrapper.cpp create mode 100644 _wrapper/src/refprop_wrapper.h diff --git a/Examples.mo b/Examples.mo index 736222f..a40086b 100644 --- a/Examples.mo +++ b/Examples.mo @@ -1,19 +1,6 @@ within REFPROP2Modelica; package Examples "Demonstration of the usage of the library" - extends Modelica.Icons.ExamplesPackage; - - - - - - - - - - - - annotation(preferedView="info", __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index 08eea80..cf5624e 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -144,16 +144,9 @@ equation h, X, phaseInput); - // Compute the remaining variables. - // It is not possible to use the standard functions like - // d = density(state), because differentiation for index - // reduction and change of state variables would not be supported - // density_ph(), which has an appropriate derivative annotation, - // is used instead. The implementation of density_ph() uses - // setState with the same inputs, so there's no actual overhead - d = density_phX(p, h, X, phaseInput); - s = specificEntropy_phX(p, h, X, phaseInput); - T = temperature_phX(p, h, X, phaseInput); + d = density(state); + s = specificEntropy(state); + T = temperature(state); elseif (basePropertiesInputChoice == InputChoice.dTX) then state = setState_dTX( diff --git a/Interfaces/package.order b/Interfaces/package.order index 475bb51..4f06915 100644 --- a/Interfaces/package.order +++ b/Interfaces/package.order @@ -1,4 +1,4 @@ -PureSubstanceInputChoice MixtureInputChoice -REFPROPMixtureTwoPhaseMedium PartialMixtureTwoPhaseMedium +PureSubstanceInputChoice +REFPROPMixtureTwoPhaseMedium diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo new file mode 100644 index 0000000..a6624c8 --- /dev/null +++ b/Testers/PropsMixtureNH3H2O.mo @@ -0,0 +1,32 @@ +within REFPROP2Modelica.Testers; +model PropsMixtureNH3H2O +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( + final substanceNames={"ammonia","water"}, + inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); + + Medium.ThermodynamicState state; + + Modelica.SIunits.Density d; + Modelica.SIunits.Temperature T; + Real[2] X; + + Modelica.SIunits.AbsolutePressure p; + Real q; + +protected + Modelica.SIunits.Temperature T_init = 400; + Real[2] X_init = {0.5,0.5}; + Modelica.SIunits.AbsolutePressure p_init = Medium.pressure_TqX(T_init,0.5,X_init); +initial algorithm + d := Medium.density_pTX(p_init,T_init,X_init); +equation + der(d) = 0; + X[1] = 0.25 + 0.5 * time; + X[2] = 1 - X[1]; + T = 350 + 100 * time; + state = Medium.setState_dTX(d,T,X); + + p = Medium.pressure(state); + q = Medium.vapourQuality(state); + +end PropsMixtureNH3H2O; diff --git a/Testers/package.order b/Testers/package.order index 6804795..cbda809 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -1,6 +1,7 @@ PentaneTester -R410mixTester -PropsMixtureTwo PropsMixture +PropsMixtureTwo PropsPureSubstance +R410mixTester Water_MixtureTwoPhase_pT +PropsMixtureNH3H2O diff --git a/_wrapper/Makefile b/_wrapper/Makefile new file mode 100644 index 0000000..a77465a --- /dev/null +++ b/_wrapper/Makefile @@ -0,0 +1,178 @@ +# ============================================================================ +# Name : Makefile +# Author : Jorrit Wronski (jowr@mek.dtu.dk) +# Version : 0.6.1 +# Copyright : Use and modify at your own risk. +# Description : Makefile for Refprop from Fortran and C++ tests. +# ============================================================================ +# The installation procedure should be as follows: +# 0) make sure to have librefprop.so available on your system +# 1) make header library +# 2) sudo make install +# 3) sudo make fixit +# ============================================================================ +# general commands: +RM := rm -f +CP := cp +CH := chmod 0644 +MK := mkdir -p +LD := ldconfig +LN := ln -sf + +# used for the output +MAJORVERSION =0 +MINORVERSION =7.0 +THENAME =refprop_wrapper +LIBRARYEXTENSION =.so +THETEST =refpropwrappertest + +# find . -type f -print0 | xargs -0 sed -i 's/!REFPROP_wrapper/refprop_wrapper/g' +# find . -type f -print0 | xargs -0 sed -i 's/refprop_wrapper/refprop_wrapper/g' +########################################################### +# Setting the directories for library, header and +# binary files created in this makefile. +########################################################### +SRCDIR =./src +# DYMDIR =/opt/dymola +# LIBINST =$(DYMDIR)/bin/lib +# HEADINST =$(DYMDIR)/source +LIBINST =/usr/local/lib +HEADINST =/usr/local/include +BINDIR =./bin + + +LIBS =-lrefprop -ldl +OPTFLAGS =-O3 -ffast-math# -ffloat-store # optimisation, remove for debugging + +########################################################### +# Change these lines if you are using a different C++ +# compiler or if you would like to use other flags. +########################################################### +CPPC =g++ +CPPFLAGS =$(OPTFLAGS) -Wall -pedantic -fbounds-check -ansi -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 +DEBUGFLAGS =-g -O3 + +########################################################### +# Change these lines if you have other needs regarding +# the generated shared library file. +########################################################### +LIBFILE =$(THENAME) +LIBRARY =lib$(THENAME) +LIBFLAGS =-rdynamic -fPIC -shared -Wl,-soname,$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) +HEADERFILE =$(THENAME) +LIBHEADER =refprop_library +HEADEREXTENSION =.h + +########################################################### +# Copy files to places recognised by the system. +########################################################### +.PHONY : install +install : install_dynamic + +.PHONY : install_dynamic +install_dynamic : header library + $(MK) $(HEADINST) $(LIBINST) + $(CP) $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(BINDIR)/$(LIBHEADER)$(HEADEREXTENSION) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) + $(CP) $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(CH) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CH) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(LD) -l $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) + $(LN) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) + $(LD) + +.PHONY : install_static +install_static : header $(LIBRARY).a + $(MK) $(HEADINST) $(LIBINST) + $(CP) $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(BINDIR)/$(LIBHEADER)$(HEADEREXTENSION) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) + $(CP) $(LIBRARY).a $(LIBINST)/$(LIBRARY).a + $(CH) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CH) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) + $(CH) $(LIBINST)/$(LIBRARY).a + $(LD) + +.PHONY : uninstall +uninstall : unfixit + $(RM) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(RM) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) + $(RM) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION)* + $(RM) $(LIBINST)/$(LIBRARY).a + +.PHONY : all +all : header library + +.PHONY : fixit +fixit : install + ln -sf $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) + ln -sf $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) + ln -sf $(LIBINST)/$(LIBRARY).a $(LIBINST)/libREFPROP_wrapper.a + +.PHONY : unfixit +unfixit : + $(RM) $(HEADINST)/REFPROP_wrapper$(HEADEREXTENSION) + $(RM) $(LIBINST)/libREFPROP_wrapper$(LIBRARYEXTENSION) + $(RM) $(LIBINST)/libREFPROP_wrapper + +########################################################## +# Compile the C++ sources into a library file that can +# be used as a shared object. +########################################################### +.PHONY : header +header : $(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(BINDIR)/$(LIBHEADER)$(HEADEREXTENSION) + +$(BINDIR)/$(HEADERFILE)$(HEADEREXTENSION): $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENSION) + $(CP) $(SRCDIR)/$(HEADERFILE)$(HEADEREXTENSION) $(BINDIR) + +$(BINDIR)/$(LIBHEADER)$(HEADEREXTENSION): $(SRCDIR)/$(LIBHEADER)$(HEADEREXTENSION) + $(CP) $(SRCDIR)/$(LIBHEADER)$(HEADEREXTENSION) $(BINDIR) + +.PHONY : library +library : $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) + +$(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): $(SRCDIR)/$(LIBFILE).o + $(CPPC) $(LIBFLAGS) $(CPPFLAGS) -o $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(SRCDIR)/$(LIBFILE).o $(LIBS) + + +########################################################### +# Compile the wrapper class tests. +########################################################### +.PHONY : test +test : $(BINDIR)/$(THETEST) + +$(BINDIR)/$(THETEST) : #$(SRCDIR)/$(THETEST).o + $(CPPC) $(DEBUGFLAGS) -o $(SRCDIR)/$(LIBFILE).o -c $(SRCDIR)/$(LIBFILE).cpp $(LIBS) + $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) + +# .PHONY : ian +# ian : $(BINDIR)/$(THETEST).ian +# +# $(BINDIR)/$(THETEST).ian : $(SRCDIR)/$(THETEST).ian.o $(SRCDIR)/$(LIBFILE).ian.o +# $(CPPC) $(CPPFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).ian.o $(SRCDIR)/$(LIBFILE).ian.o -lPocoFoundation + +########################################################### +# General rulesets for compilation. +########################################################### +$(SRCDIR)/%.o : $(SRCDIR)/%.cpp + $(CPPC) $(CPPFLAGS) -o $(SRCDIR)/$*.o -c $< + +$(SRCDIR)/%.o : $(SRCDIR)/%.c + $(CC) $(CFLAGS) -o $(SRCDIR)/$*.o -c $< + +$(SRCDIR)/%.o : $(SRCDIR)/%.FOR + $(FC) $(FFLAGS) -o $(SRCDIR)/$*.o -c $< + +.PHONY: clean +clean: + $(RM) **.o **.so **.mod $(BINDIR)/* $(SRCDIR)/*.o + +########################################################### +# Create the documentation from annotations in the source +# files with DOXYGEN, a configuration file is needed. +########################################################### +.PHONY : doc +doc : doc/Doxyfile + doxygen doc/Doxyfile + cd doc/latex ; \ + make all + \ No newline at end of file diff --git a/_wrapper/Makefile.bat b/_wrapper/Makefile.bat new file mode 100644 index 0000000..66fda8d --- /dev/null +++ b/_wrapper/Makefile.bat @@ -0,0 +1,28 @@ +@echo off +setlocal +REM ============================================================================ +REM Name : Makefile.bat +REM Author : Jorrit Wronski (jowr@mek.dtu.dk) +REM Version : 0.6 +REM Copyright : Use and modify at your own risk. +REM Description : Batch script to install the static wrapper library +REM ============================================================================ +REM The installation procedure should be as follows: +REM 0) make sure to have the refprop.dll available on your system +REM 1) Check the paths in this file and correct them if necessary. +REM 2) run this file +REM ============================================================================ +REM To compile the sources you can use +cd src +cl /c /EHsc refprop_wrapper.cpp +lib refprop_wrapper.obj +cd .. +REM ============================================================================ +REM +REM Set the required directories, could be %ProgramFiles% or %ProgramFiles(x86)% +SET PROG_DIR=%ProgramFiles% +SET DYMO_VER=Dymola 2013 +SET DYMO_DIR=%PROG_DIR%\%DYMO_VER% +COPY "src\refprop_wrapper.lib" "%DYMO_DIR%\bin\lib\" +COPY "src\refprop_wrapper.h" "%DYMO_DIR%\Source\" +COPY "src\refprop_library.h" "%DYMO_DIR%\Source\" diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h new file mode 100644 index 0000000..5231ae8 --- /dev/null +++ b/_wrapper/bin/refprop_library.h @@ -0,0 +1,788 @@ + +#ifndef REFPROP_LIB_H +#define REFPROP_LIB_H + +/* +// The idea here is to have a common header for Windows +// and gcc-like systems. The Windows branch should cover the +// functions provided by the .dll and the gcc part covers +// the compiled .so/.dym file. Name changes caused by gfortran +// are respected and should be accounted for. +*/ +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +// Do some manual changes to the function names +// if needed, uses CoolProp platform detection. +#if defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV __stdcall +// Do not redefine function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. Macros still need a value for the +// name function used below. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define RESIDUALdll RESIDUALdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll +#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # if defined( _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define RESIDUALdll residualdll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +#else // #elif defined(__ISLINUX__) +// Set some dummy names for the compiler +# define CALLCONV +# define RPVersion NOTAVAILABLE +# define SETPATHdll setpathdll +# define ABFL1dll abfl1dll +# define ABFL2dll abfl2dll +# define ACTVYdll actvydll +# define AGdll agdll +# define CCRITdll ccritdll +# define CP0dll cp0dll +# define CRITPdll critpdll +# define CSATKdll csatkdll +# define CV2PKdll cv2pkdll +# define CVCPKdll cvcpkdll +# define CVCPdll cvcpdll +# define DBDTdll dbdtdll +# define DBFL1dll dbfl1dll +# define DBFL2dll dbfl2dll +# define DDDPdll dddpdll +# define DDDTdll dddtdll +# define DEFLSHdll deflshdll +# define DHD1dll dhd1dll +# define DHFL1dll dhfl1dll +# define DHFL2dll dhfl2dll +# define DHFLSHdll dhflshdll +# define DIELECdll dielecdll +# define DOTFILLdll dotfilldll +# define DPDD2dll dpdd2dll +# define DPDDKdll dpddkdll +# define DPDDdll dpdddll +# define DPDTKdll dpdtkdll +# define DPDTdll dpdtdll +# define DPTSATKdll dptsatkdll +# define DSFLSHdll dsflshdll +# define DSFL1dll dsfl1dll +# define DSFL2dll dsfl2dll +# define ENTHALdll enthaldll +# define ENTROdll entrodll +# define ESFLSHdll esflshdll +# define FGCTYdll fgctydll +# define FPVdll fpvdll +# define GERG04dll gerg04dll +# define GETFIJdll getfijdll +# define GETKTVdll getktvdll +# define GIBBSdll gibbsdll +# define HSFLSHdll hsflshdll +# define INFOdll infodll +# define LIMITKdll limitkdll +# define LIMITSdll limitsdll +# define LIMITXdll limitxdll +# define MELTPdll meltpdll +# define MELTTdll melttdll +# define MLTH2Odll mlth2odll +# define NAMEdll namedll +# define PDFL1dll pdfl1dll +# define PDFLSHdll pdflshdll +# define PEFLSHdll peflshdll +# define PHFL1dll phfl1dll +# define PHFLSHdll phflshdll +# define PQFLSHdll pqflshdll +# define PREOSdll preosdll +# define PRESSdll pressdll +# define PSFL1dll psfl1dll +# define PSFLSHdll psflshdll +# define PUREFLDdll pureflddll +# define QMASSdll qmassdll +# define QMOLEdll qmoledll +# define RESIDUALdll residualdll +# define SATDdll satddll +# define SATEdll satedll +# define SATHdll sathdll +# define SATPdll satpdll +# define SATSdll satsdll +# define SATTdll sattdll +# define SETAGAdll setagadll +# define SETKTVdll setktvdll +# define SETMIXdll setmixdll +# define SETMODdll setmoddll +# define SETREFdll setrefdll +# define SETUPdll setupdll +//# define SPECGRdll specgrdll // not found in library +# define SUBLPdll sublpdll +# define SUBLTdll subltdll +# define SURFTdll surftdll +# define SURTENdll surtendll +# define TDFLSHdll tdflshdll +# define TEFLSHdll teflshdll +# define THERM0dll therm0dll +# define THERM2dll therm2dll +# define THERM3dll therm3dll +# define THERMdll thermdll +# define THFLSHdll thflshdll +# define TPFLSHdll tpflshdll +# define TPFL2dll tpfl2dll +# define TPRHOdll tprhodll +# define TQFLSHdll tqflshdll +# define TRNPRPdll trnprpdll +# define TSFLSHdll tsflshdll +# define VIRBdll virbdll +# define VIRCdll vircdll +# define WMOLdll wmoldll +# define XMASSdll xmassdll +# define XMOLEdll xmoledll +#endif // else branch +// +// +// Only continue if function names have been defined. +// We might want to include some more tests here... +#if defined(RPVersion) +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#if defined(__cplusplus) +extern "C" { +#endif + typedef void (CALLCONV RPVersion_TYPE)( char* ); + typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + // + typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); + typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); + typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); + typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); + typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); + typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); + typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); + typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); + typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); + typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PREOSdll_TYPE)(long &); + typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PUREFLDdll_TYPE)(long &); + typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); + typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); + typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); + typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); + typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); + typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); + typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); +// +// Disabled because we prefer pointers here! +// // Declare the functions for direct access, +// RPVersion_TYPE RPVersion; +// SETPATHdll_TYPE SETPATHdll; +// ABFL1dll_TYPE ABFL1dll; +// ABFL2dll_TYPE ABFL2dll; +// ACTVYdll_TYPE ACTVYdll; +// AGdll_TYPE AGdll; +// CCRITdll_TYPE CCRITdll; +// CP0dll_TYPE CP0dll; +// CRITPdll_TYPE CRITPdll; +// CSATKdll_TYPE CSATKdll; +// CV2PKdll_TYPE CV2PKdll; +// CVCPKdll_TYPE CVCPKdll; +// CVCPdll_TYPE CVCPdll; +// DBDTdll_TYPE DBDTdll; +// DBFL1dll_TYPE DBFL1dll; +// DBFL2dll_TYPE DBFL2dll; +// DDDPdll_TYPE DDDPdll; +// DDDTdll_TYPE DDDTdll; +// DEFLSHdll_TYPE DEFLSHdll; +// DHD1dll_TYPE DHD1dll; +// DHFLSHdll_TYPE DHFLSHdll; +// DHFL1dll_TYPE DHFL1dll; +// DHFL2dll_TYPE DHFL2dll; +// DIELECdll_TYPE DIELECdll; +// DOTFILLdll_TYPE DOTFILLdll; +// DPDD2dll_TYPE DPDD2dll; +// DPDDKdll_TYPE DPDDKdll; +// DPDDdll_TYPE DPDDdll; +// DPDTKdll_TYPE DPDTKdll; +// DPDTdll_TYPE DPDTdll; +// DPTSATKdll_TYPE DPTSATKdll; +// DSFLSHdll_TYPE DSFLSHdll; +// DSFL1dll_TYPE DSFL1dll; +// DSFL2dll_TYPE DSFL2dll; +// ENTHALdll_TYPE ENTHALdll; +// ENTROdll_TYPE ENTROdll; +// ESFLSHdll_TYPE ESFLSHdll; +// FGCTYdll_TYPE FGCTYdll; +// FPVdll_TYPE FPVdll; +// GERG04dll_TYPE GERG04dll; +// GETFIJdll_TYPE GETFIJdll; +// GETKTVdll_TYPE GETKTVdll; +// GIBBSdll_TYPE GIBBSdll; +// HSFLSHdll_TYPE HSFLSHdll; +// INFOdll_TYPE INFOdll; +// LIMITKdll_TYPE LIMITKdll; +// LIMITSdll_TYPE LIMITSdll; +// LIMITXdll_TYPE LIMITXdll; +// MELTPdll_TYPE MELTPdll; +// MELTTdll_TYPE MELTTdll; +// MLTH2Odll_TYPE MLTH2Odll; +// NAMEdll_TYPE NAMEdll; +// PDFL1dll_TYPE PDFL1dll; +// PDFLSHdll_TYPE PDFLSHdll; +// PEFLSHdll_TYPE PEFLSHdll; +// PHFL1dll_TYPE PHFL1dll; +// PHFLSHdll_TYPE PHFLSHdll; +// PQFLSHdll_TYPE PQFLSHdll; +// PREOSdll_TYPE PREOSdll; +// PRESSdll_TYPE PRESSdll; +// PSFL1dll_TYPE PSFL1dll; +// PSFLSHdll_TYPE PSFLSHdll; +// PUREFLDdll_TYPE PUREFLDdll; +// QMASSdll_TYPE QMASSdll; +// QMOLEdll_TYPE QMOLEdll; +// SATDdll_TYPE SATDdll; +// SATEdll_TYPE SATEdll; +// SATHdll_TYPE SATHdll; +// SATPdll_TYPE SATPdll; +// SATSdll_TYPE SATSdll; +// SATTdll_TYPE SATTdll; +// SETAGAdll_TYPE SETAGAdll; +// SETKTVdll_TYPE SETKTVdll; +// SETMIXdll_TYPE SETMIXdll; +// SETMODdll_TYPE SETMODdll; +// SETREFdll_TYPE SETREFdll; +// SETUPdll_TYPE SETUPdll; +//// SPECGRdll_TYPE SPECGRdll; // not found in library +// SUBLPdll_TYPE SUBLPdll; +// SUBLTdll_TYPE SUBLTdll; +// SURFTdll_TYPE SURFTdll; +// SURTENdll_TYPE SURTENdll; +// TDFLSHdll_TYPE TDFLSHdll; +// TEFLSHdll_TYPE TEFLSHdll; +// THERM0dll_TYPE THERM0dll; +// THERM2dll_TYPE THERM2dll; +// THERM3dll_TYPE THERM3dll; +// THERMdll_TYPE THERMdll; +// THFLSHdll_TYPE THFLSHdll; +// TPFLSHdll_TYPE TPFLSHdll; +// TPFL2dll_TYPE TPFL2dll; +// TPRHOdll_TYPE TPRHOdll; +// TQFLSHdll_TYPE TQFLSHdll; +// TRNPRPdll_TYPE TRNPRPdll; +// TSFLSHdll_TYPE TSFLSHdll; +// VIRBdll_TYPE VIRBdll; +// VIRCdll_TYPE VIRCdll; +// WMOLdll_TYPE WMOLdll; +// XMASSdll_TYPE XMASSdll; +// XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus +#endif // defined(RPversion) +#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_library.h b/_wrapper/src/refprop_library.h new file mode 100644 index 0000000..5231ae8 --- /dev/null +++ b/_wrapper/src/refprop_library.h @@ -0,0 +1,788 @@ + +#ifndef REFPROP_LIB_H +#define REFPROP_LIB_H + +/* +// The idea here is to have a common header for Windows +// and gcc-like systems. The Windows branch should cover the +// functions provided by the .dll and the gcc part covers +// the compiled .so/.dym file. Name changes caused by gfortran +// are respected and should be accounted for. +*/ +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +// Do some manual changes to the function names +// if needed, uses CoolProp platform detection. +#if defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV __stdcall +// Do not redefine function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. Macros still need a value for the +// name function used below. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define RESIDUALdll RESIDUALdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll +#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # if defined( _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define RESIDUALdll residualdll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +#else // #elif defined(__ISLINUX__) +// Set some dummy names for the compiler +# define CALLCONV +# define RPVersion NOTAVAILABLE +# define SETPATHdll setpathdll +# define ABFL1dll abfl1dll +# define ABFL2dll abfl2dll +# define ACTVYdll actvydll +# define AGdll agdll +# define CCRITdll ccritdll +# define CP0dll cp0dll +# define CRITPdll critpdll +# define CSATKdll csatkdll +# define CV2PKdll cv2pkdll +# define CVCPKdll cvcpkdll +# define CVCPdll cvcpdll +# define DBDTdll dbdtdll +# define DBFL1dll dbfl1dll +# define DBFL2dll dbfl2dll +# define DDDPdll dddpdll +# define DDDTdll dddtdll +# define DEFLSHdll deflshdll +# define DHD1dll dhd1dll +# define DHFL1dll dhfl1dll +# define DHFL2dll dhfl2dll +# define DHFLSHdll dhflshdll +# define DIELECdll dielecdll +# define DOTFILLdll dotfilldll +# define DPDD2dll dpdd2dll +# define DPDDKdll dpddkdll +# define DPDDdll dpdddll +# define DPDTKdll dpdtkdll +# define DPDTdll dpdtdll +# define DPTSATKdll dptsatkdll +# define DSFLSHdll dsflshdll +# define DSFL1dll dsfl1dll +# define DSFL2dll dsfl2dll +# define ENTHALdll enthaldll +# define ENTROdll entrodll +# define ESFLSHdll esflshdll +# define FGCTYdll fgctydll +# define FPVdll fpvdll +# define GERG04dll gerg04dll +# define GETFIJdll getfijdll +# define GETKTVdll getktvdll +# define GIBBSdll gibbsdll +# define HSFLSHdll hsflshdll +# define INFOdll infodll +# define LIMITKdll limitkdll +# define LIMITSdll limitsdll +# define LIMITXdll limitxdll +# define MELTPdll meltpdll +# define MELTTdll melttdll +# define MLTH2Odll mlth2odll +# define NAMEdll namedll +# define PDFL1dll pdfl1dll +# define PDFLSHdll pdflshdll +# define PEFLSHdll peflshdll +# define PHFL1dll phfl1dll +# define PHFLSHdll phflshdll +# define PQFLSHdll pqflshdll +# define PREOSdll preosdll +# define PRESSdll pressdll +# define PSFL1dll psfl1dll +# define PSFLSHdll psflshdll +# define PUREFLDdll pureflddll +# define QMASSdll qmassdll +# define QMOLEdll qmoledll +# define RESIDUALdll residualdll +# define SATDdll satddll +# define SATEdll satedll +# define SATHdll sathdll +# define SATPdll satpdll +# define SATSdll satsdll +# define SATTdll sattdll +# define SETAGAdll setagadll +# define SETKTVdll setktvdll +# define SETMIXdll setmixdll +# define SETMODdll setmoddll +# define SETREFdll setrefdll +# define SETUPdll setupdll +//# define SPECGRdll specgrdll // not found in library +# define SUBLPdll sublpdll +# define SUBLTdll subltdll +# define SURFTdll surftdll +# define SURTENdll surtendll +# define TDFLSHdll tdflshdll +# define TEFLSHdll teflshdll +# define THERM0dll therm0dll +# define THERM2dll therm2dll +# define THERM3dll therm3dll +# define THERMdll thermdll +# define THFLSHdll thflshdll +# define TPFLSHdll tpflshdll +# define TPFL2dll tpfl2dll +# define TPRHOdll tprhodll +# define TQFLSHdll tqflshdll +# define TRNPRPdll trnprpdll +# define TSFLSHdll tsflshdll +# define VIRBdll virbdll +# define VIRCdll vircdll +# define WMOLdll wmoldll +# define XMASSdll xmassdll +# define XMOLEdll xmoledll +#endif // else branch +// +// +// Only continue if function names have been defined. +// We might want to include some more tests here... +#if defined(RPVersion) +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#if defined(__cplusplus) +extern "C" { +#endif + typedef void (CALLCONV RPVersion_TYPE)( char* ); + typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + // + typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); + typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); + typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); + typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); + typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); + typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); + typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); + typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); + typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); + typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PREOSdll_TYPE)(long &); + typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PUREFLDdll_TYPE)(long &); + typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); + typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); + typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); + typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); + typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); + typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); + typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); +// +// Disabled because we prefer pointers here! +// // Declare the functions for direct access, +// RPVersion_TYPE RPVersion; +// SETPATHdll_TYPE SETPATHdll; +// ABFL1dll_TYPE ABFL1dll; +// ABFL2dll_TYPE ABFL2dll; +// ACTVYdll_TYPE ACTVYdll; +// AGdll_TYPE AGdll; +// CCRITdll_TYPE CCRITdll; +// CP0dll_TYPE CP0dll; +// CRITPdll_TYPE CRITPdll; +// CSATKdll_TYPE CSATKdll; +// CV2PKdll_TYPE CV2PKdll; +// CVCPKdll_TYPE CVCPKdll; +// CVCPdll_TYPE CVCPdll; +// DBDTdll_TYPE DBDTdll; +// DBFL1dll_TYPE DBFL1dll; +// DBFL2dll_TYPE DBFL2dll; +// DDDPdll_TYPE DDDPdll; +// DDDTdll_TYPE DDDTdll; +// DEFLSHdll_TYPE DEFLSHdll; +// DHD1dll_TYPE DHD1dll; +// DHFLSHdll_TYPE DHFLSHdll; +// DHFL1dll_TYPE DHFL1dll; +// DHFL2dll_TYPE DHFL2dll; +// DIELECdll_TYPE DIELECdll; +// DOTFILLdll_TYPE DOTFILLdll; +// DPDD2dll_TYPE DPDD2dll; +// DPDDKdll_TYPE DPDDKdll; +// DPDDdll_TYPE DPDDdll; +// DPDTKdll_TYPE DPDTKdll; +// DPDTdll_TYPE DPDTdll; +// DPTSATKdll_TYPE DPTSATKdll; +// DSFLSHdll_TYPE DSFLSHdll; +// DSFL1dll_TYPE DSFL1dll; +// DSFL2dll_TYPE DSFL2dll; +// ENTHALdll_TYPE ENTHALdll; +// ENTROdll_TYPE ENTROdll; +// ESFLSHdll_TYPE ESFLSHdll; +// FGCTYdll_TYPE FGCTYdll; +// FPVdll_TYPE FPVdll; +// GERG04dll_TYPE GERG04dll; +// GETFIJdll_TYPE GETFIJdll; +// GETKTVdll_TYPE GETKTVdll; +// GIBBSdll_TYPE GIBBSdll; +// HSFLSHdll_TYPE HSFLSHdll; +// INFOdll_TYPE INFOdll; +// LIMITKdll_TYPE LIMITKdll; +// LIMITSdll_TYPE LIMITSdll; +// LIMITXdll_TYPE LIMITXdll; +// MELTPdll_TYPE MELTPdll; +// MELTTdll_TYPE MELTTdll; +// MLTH2Odll_TYPE MLTH2Odll; +// NAMEdll_TYPE NAMEdll; +// PDFL1dll_TYPE PDFL1dll; +// PDFLSHdll_TYPE PDFLSHdll; +// PEFLSHdll_TYPE PEFLSHdll; +// PHFL1dll_TYPE PHFL1dll; +// PHFLSHdll_TYPE PHFLSHdll; +// PQFLSHdll_TYPE PQFLSHdll; +// PREOSdll_TYPE PREOSdll; +// PRESSdll_TYPE PRESSdll; +// PSFL1dll_TYPE PSFL1dll; +// PSFLSHdll_TYPE PSFLSHdll; +// PUREFLDdll_TYPE PUREFLDdll; +// QMASSdll_TYPE QMASSdll; +// QMOLEdll_TYPE QMOLEdll; +// SATDdll_TYPE SATDdll; +// SATEdll_TYPE SATEdll; +// SATHdll_TYPE SATHdll; +// SATPdll_TYPE SATPdll; +// SATSdll_TYPE SATSdll; +// SATTdll_TYPE SATTdll; +// SETAGAdll_TYPE SETAGAdll; +// SETKTVdll_TYPE SETKTVdll; +// SETMIXdll_TYPE SETMIXdll; +// SETMODdll_TYPE SETMODdll; +// SETREFdll_TYPE SETREFdll; +// SETUPdll_TYPE SETUPdll; +//// SPECGRdll_TYPE SPECGRdll; // not found in library +// SUBLPdll_TYPE SUBLPdll; +// SUBLTdll_TYPE SUBLTdll; +// SURFTdll_TYPE SURFTdll; +// SURTENdll_TYPE SURTENdll; +// TDFLSHdll_TYPE TDFLSHdll; +// TEFLSHdll_TYPE TEFLSHdll; +// THERM0dll_TYPE THERM0dll; +// THERM2dll_TYPE THERM2dll; +// THERM3dll_TYPE THERM3dll; +// THERMdll_TYPE THERMdll; +// THFLSHdll_TYPE THFLSHdll; +// TPFLSHdll_TYPE TPFLSHdll; +// TPFL2dll_TYPE TPFL2dll; +// TPRHOdll_TYPE TPRHOdll; +// TQFLSHdll_TYPE TQFLSHdll; +// TRNPRPdll_TYPE TRNPRPdll; +// TSFLSHdll_TYPE TSFLSHdll; +// VIRBdll_TYPE VIRBdll; +// VIRCdll_TYPE VIRCdll; +// WMOLdll_TYPE WMOLdll; +// XMASSdll_TYPE XMASSdll; +// XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus +#endif // defined(RPversion) +#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp new file mode 100644 index 0000000..945017d --- /dev/null +++ b/_wrapper/src/refprop_wrapper.cpp @@ -0,0 +1,2205 @@ +/* + This is a wrapper file for the Refprop library. It does not include + any functionality besides providing the connection to Refprop. + + The current version was developed by Jorrit Wronski (jowr@mek.dtu.dk) + based on Henning Francke's (francke@gfz-potsdam.de) wrapper. A little + inspiration also came from Ian Bell's (ian.h.bell@gmail.com) wrapper + used in CoolProp - http://coolprop.sourceforge.net/ + + Compatible to the Modelica interface developed by Henning Francke + (francke@gfz-potsdam.de) and his first wrapper class that you can + find in the folder with version 0.5 for Windows systems. +*/ +/* + * Here are the included files + */ +#include "refprop_library.h" +#include "refprop_wrapper.h" + +#include +#include +#include +#include +#include +#include + +#if defined(__ISWINDOWS__) +#include +#define pathSep STR_VALUE(\\) +#define libName STR_VALUE(refprop.dll) +#define _CRT_SECURE_NO_WARNINGS +#elif defined(__ISLINUX__) +#include +#define pathSep STR_VALUE(/) +#define libName STR_VALUE(librefprop.so) +#elif defined(__ISAPPLE__) +#include +#define pathSep STR_VALUE(/) +#define libName STR_VALUE(librefprop.dylib) +#endif + + +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define refpropcharlong 10000 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +/* + * Define pointer to library as well as the + * strings we need to determine whether a + * call to SETUPdll is needed. + */ +#if defined(__ISWINDOWS__) +HINSTANCE RefpropdllInstance= NULL; +#elif defined(__ISLINUX__) +void *RefpropdllInstance = NULL; +#elif defined(__ISAPPLE__) +void *RefpropdllInstance = NULL; +#else +void *RefpropdllInstance = NULL; +#endif +std::string loadedFluids; + + + +/* + * Here we define the fluid's properties. These values get updated after each + * call to Refprop and are used for caching values. I decided to use the + * Refprop units for internal data storage Be careful when converting + * properties using the molecular weight. It is stored in g/mol. + */ + long kq = 2; // all qualities are calculated on a mass basis +static const double noValue = -1e+10; + +//static const std::string FLUIDS_PATH = "fluids"; +//static const std::string LIN_LIBRARY = "librefprop.so"; +//static const std::string WIN_LIBRARY = "refprop.dll"; +//Poco::Path FLD_PATH(true); + + +// static const double noFactor = 1e+0; +// static const double presFactor = 1e+3; +// static const double viscFactor = 1e+6; +// static const double molwFactor = 1e-3; +// double energyFactor = noValue; // J/mol / g/mol * 1000g/kg = J/kg +// double densityFactor[3] = {noValue}; // mol/l * g/mol = g/l = kg/m3 for all phases +// double fractionFactor[ncmax] = {noValue}; // xkgi = xmi * mwi * mw (array) +// double qualityFactor = noValue; // qmass = qmole * mw_vap / mw + +bool debug; // set the debug flag +//long lerr; // Error return mechanism +double dhelp = noValue; + + +/* + * Properties for saturation states. "dew" refers to the dew point and + * "bub" describes the bubble point. + */ +double dtdew, dpdew, ddldew, ddvdew, dtbub, dpbub, ddlbub, ddvbub; +int flushSaturation() { + dtdew=noValue; + dpdew=noValue; + ddldew=noValue; + ddvdew=noValue; + dtbub=noValue; + dpbub=noValue; + ddlbub=noValue; + ddvbub=noValue; + if (debug) printf ("Finished flushing saturation properties.\n"); + return 0; +} + + +/* + * Most of the fluid properties are stored here. There are arrays for + * composition information as well as single values for the other + * properties. + * The flush function gets called when the state changes and the + * previously calculated are not valid anymore. A change of state also leads + * to changed saturation conditions. + */ +double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, + ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, + dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt, + ddddp, dd2pdt2, dd2pdtd, ddhdt, df, deta, dtcx, dstn; + +double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; + +double ddddp_h, ddddh_p; + +int flushProperties(){ + dt=noValue; + dp=noValue; + de=noValue; + dh=noValue; + ds=noValue; + dqmol=noValue; + dd=noValue; + dxmol[0]=noValue; + ddl=noValue; + ddv=noValue; + dxmoll[0]=noValue; + dxmolv[0]=noValue; + dCv=noValue; + dCp=noValue; + dw=noValue; + dwliq=noValue; + dwvap=noValue; + dhjt=noValue; + dZ[0]=noValue; + dA=noValue; + dG=noValue; + dxkappa=noValue; + dbeta=noValue; + ddpdd=noValue; + dd2pdd2=noValue; + ddpdt=noValue; + ddddt=noValue; + ddddp=noValue; + dd2pdt2=noValue; + dd2pdtd=noValue; + ddhdt=noValue; + df=noValue; + deta=noValue; + dtcx=noValue; + dstn=noValue; + + ddhdt_d=noValue; + ddhdt_p=noValue; + ddhdd_t=noValue; + ddhdd_p=noValue; + ddhdp_t=noValue; + ddhdp_d=noValue; + + ddddp_h=noValue; + ddddh_p=noValue; + + if (debug) printf ("Finished flushing normal fluid properties.\n"); + return flushSaturation(); +} + + +/* + * Properties that are constants for pure fluids. Hence, the flushing + * function gets called when a new fluid is loaded. In case of a mixture, + * a change of composition also triggers a flushing since this also + * changes those that also exist for mixtures. + * A change of composition or fluid always leads to a flushing of the + * other properties. + */ +long lnc; // number of components +double dwm, dttp, dtnbp, dtc, dpc, ddc, dZc, dacf, ddip, drgas; +int flushConstants() { + //lnc = -1; + dwm = noValue; + dttp = noValue; + dtnbp = noValue; + dtc = noValue; + dpc = noValue; + ddc = noValue; + dZc = noValue; + dacf = noValue; + ddip = noValue; + drgas = noValue; + if (debug) printf ("Finished flushing fluid/mixture \"constants\".\n"); + return flushProperties(); +} + +char hfmix[] = "HMX.BNC"; +char hrf[] = "DEF"; + + + + + +/* + * Define functions as pointers and initialise them to NULL + * Declare the functions for direct access + */ +RPVersion_POINTER RPVersion; +SETPATHdll_POINTER SETPATHdll; +ABFL1dll_POINTER ABFL1dll; +ABFL2dll_POINTER ABFL2dll; +ACTVYdll_POINTER ACTVYdll; +AGdll_POINTER AGdll; +CCRITdll_POINTER CCRITdll; +CP0dll_POINTER CP0dll; +CRITPdll_POINTER CRITPdll; +CSATKdll_POINTER CSATKdll; +CV2PKdll_POINTER CV2PKdll; +CVCPKdll_POINTER CVCPKdll; +CVCPdll_POINTER CVCPdll; +DBDTdll_POINTER DBDTdll; +DBFL1dll_POINTER DBFL1dll; +DBFL2dll_POINTER DBFL2dll; +DDDPdll_POINTER DDDPdll; +DDDTdll_POINTER DDDTdll; +DEFLSHdll_POINTER DEFLSHdll; +DHD1dll_POINTER DHD1dll; +DHFLSHdll_POINTER DHFLSHdll; +DHFL1dll_POINTER DHFL1dll; +DHFL2dll_POINTER DHFL2dll; +DIELECdll_POINTER DIELECdll; +DOTFILLdll_POINTER DOTFILLdll; +DPDD2dll_POINTER DPDD2dll; +DPDDKdll_POINTER DPDDKdll; +DPDDdll_POINTER DPDDdll; +DPDTKdll_POINTER DPDTKdll; +DPDTdll_POINTER DPDTdll; +DPTSATKdll_POINTER DPTSATKdll; +DSFLSHdll_POINTER DSFLSHdll; +DSFL1dll_POINTER DSFL1dll; +DSFL2dll_POINTER DSFL2dll; +ENTHALdll_POINTER ENTHALdll; +ENTROdll_POINTER ENTROdll; +ESFLSHdll_POINTER ESFLSHdll; +FGCTYdll_POINTER FGCTYdll; +FPVdll_POINTER FPVdll; +GERG04dll_POINTER GERG04dll; +GETFIJdll_POINTER GETFIJdll; +GETKTVdll_POINTER GETKTVdll; +GIBBSdll_POINTER GIBBSdll; +HSFLSHdll_POINTER HSFLSHdll; +INFOdll_POINTER INFOdll; +LIMITKdll_POINTER LIMITKdll; +LIMITSdll_POINTER LIMITSdll; +LIMITXdll_POINTER LIMITXdll; +MELTPdll_POINTER MELTPdll; +MELTTdll_POINTER MELTTdll; +MLTH2Odll_POINTER MLTH2Odll; +NAMEdll_POINTER NAMEdll; +PDFL1dll_POINTER PDFL1dll; +PDFLSHdll_POINTER PDFLSHdll; +PEFLSHdll_POINTER PEFLSHdll; +PHFL1dll_POINTER PHFL1dll; +PHFLSHdll_POINTER PHFLSHdll; +PQFLSHdll_POINTER PQFLSHdll; +PREOSdll_POINTER PREOSdll; +PRESSdll_POINTER PRESSdll; +PSFL1dll_POINTER PSFL1dll; +PSFLSHdll_POINTER PSFLSHdll; +PUREFLDdll_POINTER PUREFLDdll; +QMASSdll_POINTER QMASSdll; +QMOLEdll_POINTER QMOLEdll; +RESIDUALdll_POINTER RESIDUALdll; +SATDdll_POINTER SATDdll; +SATEdll_POINTER SATEdll; +SATHdll_POINTER SATHdll; +SATPdll_POINTER SATPdll; +SATSdll_POINTER SATSdll; +SATTdll_POINTER SATTdll; +SETAGAdll_POINTER SETAGAdll; +SETKTVdll_POINTER SETKTVdll; +SETMIXdll_POINTER SETMIXdll; +SETMODdll_POINTER SETMODdll; +SETREFdll_POINTER SETREFdll; +SETUPdll_POINTER SETUPdll; +// SPECGRdll_POINTER SPECGRdll; // not found in library +SUBLPdll_POINTER SUBLPdll; +SUBLTdll_POINTER SUBLTdll; +SURFTdll_POINTER SURFTdll; +SURTENdll_POINTER SURTENdll; +TDFLSHdll_POINTER TDFLSHdll; +TEFLSHdll_POINTER TEFLSHdll; +THERM0dll_POINTER THERM0dll; +THERM2dll_POINTER THERM2dll; +THERM3dll_POINTER THERM3dll; +THERMdll_POINTER THERMdll; +THFLSHdll_POINTER THFLSHdll; +TPFLSHdll_POINTER TPFLSHdll; +TPFL2dll_POINTER TPFL2dll; +TPRHOdll_POINTER TPRHOdll; +TQFLSHdll_POINTER TQFLSHdll; +TRNPRPdll_POINTER TRNPRPdll; +TSFLSHdll_POINTER TSFLSHdll; +VIRBdll_POINTER VIRBdll; +VIRCdll_POINTER VIRCdll; +WMOLdll_POINTER WMOLdll; +XMASSdll_POINTER XMASSdll; +XMOLEdll_POINTER XMOLEdll; + + +/* + * Helper function to split strings the + * Python way. Taken from CoolProp. + */ +std::vector strsplit(std::string s, char del) { + int iL = 0, iR = 0, N; + N = s.size(); + std::vector v; + // Find the first instance of the delimiter + iR = s.find_first_of(del); + // Delimiter not found, return the same string again + if (iR < 0) { + v.push_back(s); + return v; + } + while (iR != N-1) { + v.push_back(s.substr(iL,iR-iL)); + iL = iR; + iR = s.find_first_of(del,iR+1); + // Move the iL to the right to avoid the delimiter + iL += 1; + if (iR == (int)std::string::npos) { + v.push_back(s.substr(iL,N-iL)); + break; + } + } + return v; +} + +// http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c +bool strCompare(const std::string& str1, const std::string& str2) { + if (str1.size() != str2.size()) { + return false; + } + for (std::string::const_iterator c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) { + if (tolower(*c1) != tolower(*c2)) { + return false; + } + } + return true; +} + + + + +/* + * Just a helper function control the output of + * an array. Used to debug the handling of the + * composition arrays. + */ +std::string printX(double arr[], long nc) { + std::string ret = std::string("("); + int stop = nc-1; + char buffer [10]; + + for(int i = 0; i <= (stop); i++) { + sprintf(buffer, "%1.4f", arr[i]); // four decimals + ret.append(buffer); + } + ret.append(")"); + return ret; +} + +/* + * Resolves Refprop error numbers and returns meaningful error message + * INPUT: + * in1: character specifying input + * lerr: error as a long value + * OUTPUT + * errormsg: string containing error message + * std::string: the same as errormsg + */ +std::string resolve_error(std::string in1, long lerr, char* errormsg) { + switch(lerr){ + case 0: + strcpy(errormsg,"Calculation successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 2: + if (!in1.compare("p")){ + sprintf(errormsg,"P=%f < Ptp",dp); + } else if (!in1.compare("d")){ + sprintf(errormsg,"D=%f > Dmax",dd); + } else { + strcpy(errormsg,"unknown error"); + } + break; + case 4: + if (!in1.compare("p")){ + sprintf(errormsg,"P=%f < 0",dp); + } else { + strcpy(errormsg,"unknown error"); + } + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",dt,dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + strcpy(errormsg,"unknown error"); + break; + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 101: + sprintf(errormsg,"error in opening fluid file"); + break; + case 102: + strcpy(errormsg,"error in file or premature end of file"); + break; + case -103: + strcpy(errormsg,"unknown model encountered in file"); + break; + case 104: + strcpy(errormsg,"error in setup of model"); + break; + case 105: + strcpy(errormsg,"specified model not found"); + break; + case 111: + strcpy(errormsg,"error in opening mixture file"); + break; + case 112: + strcpy(errormsg,"mixture file of wrong type"); + break; + case 114: + strcpy(errormsg,"nc<>nc from setmod"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); + break; + default: + strcpy(errormsg,"unknown error"); + break; + } + + if (debug) { + printf("Error code: %ld \n",lerr); + printf("Yields message: %s \n", errormsg); + } + return std::string(errormsg); +} + +/* + * Load the library and handle all the + * platform specific stuff. + */ +double loadLibrary() { + if (RefpropdllInstance == NULL) { // Refprop is not loaded +#if defined(__ISWINDOWS__) +#if defined(UNICODE) + RefpropdllInstance = LoadLibrary((LPCWSTR)libName); +#else + RefpropdllInstance = LoadLibrary((LPCSTR)libName); +#endif +#elif defined(__ISLINUX__) + RefpropdllInstance = dlopen(libName, RTLD_LAZY); +#elif defined(__ISAPPLE__) + RefpropdllInstance = dlopen (libName, RTLD_LAZY); +#else + throw NotImplementedError("We should not reach this point."); + RefpropdllInstance = NULL; +#endif + + if (RefpropdllInstance == NULL) { // Still NULL after loading +#if defined(__ISWINDOWS__) + printf("Library problem: "); +#elif defined(__ISLINUX__) + fputs(dlerror(), stderr); +#elif defined(__ISAPPLE__) + fputs(dlerror(), stderr); +#else + throw NotImplementedError("You should not be here."); +#endif + printf("Could not load %s\n\n", libName); + return FAIL; + } + + if (debug) printf ("Library was loaded successfully.\n"); + return OK; + } else { // Refprop was already loaded + if (debug) printf ("Library was already loaded, doing nothing.\n"); + return OK; + } + return FAIL; +} + +/* + * Multiplatform pointer handling + * Not very neat, but works. + */ +void *getFunctionPointer(char * name) { +#if defined(__ISWINDOWS__) + return (void *) GetProcAddress(RefpropdllInstance,name); +#elif defined(__ISLINUX__) + return dlsym(RefpropdllInstance, name); +#else + throw NotImplementedError("This function should not be called."); + return NULL; +#endif +} + +/* + * Moved pointer handling to a function, helps to maintain + * an overview and structures OS dependent parts + */ +double setFunctionPointers() { +// if (RefpropdllInstance != NULL) { +// printf("You only need to define the pointers once, "); +// printf("please revise your code.\n"); +// return FAIL; +// } else { // set the pointers +// if (loadLibrary() != OK) { +// printf("Refprop library %s cannot be loaded, make sure you ",libName); +// printf("installed it properly.\n"); +// return FAIL; +// } + + if (RefpropdllInstance == NULL) { + printf("Refprop library %s is not loaded, make sure you ",libName); + printf("referenced and installed it properly.\n"); + return FAIL; + } else { // set the pointers + // set the pointers, platform independent + RPVersion = (RPVersion_POINTER) getFunctionPointer((char *) RPVersion_NAME); + ABFL1dll = (ABFL1dll_POINTER) getFunctionPointer((char *) ABFL1dll_NAME); + ABFL2dll = (ABFL2dll_POINTER) getFunctionPointer((char *) ABFL2dll_NAME); + ACTVYdll = (ACTVYdll_POINTER) getFunctionPointer((char *) ACTVYdll_NAME); + AGdll = (AGdll_POINTER) getFunctionPointer((char *) AGdll_NAME); + CCRITdll = (CCRITdll_POINTER) getFunctionPointer((char *) CCRITdll_NAME); + CP0dll = (CP0dll_POINTER) getFunctionPointer((char *) CP0dll_NAME); + CRITPdll = (CRITPdll_POINTER) getFunctionPointer((char *) CRITPdll_NAME); + CSATKdll = (CSATKdll_POINTER) getFunctionPointer((char *) CSATKdll_NAME); + CV2PKdll = (CV2PKdll_POINTER) getFunctionPointer((char *) CV2PKdll_NAME); + CVCPKdll = (CVCPKdll_POINTER) getFunctionPointer((char *) CVCPKdll_NAME); + CVCPdll = (CVCPdll_POINTER) getFunctionPointer((char *) CVCPdll_NAME); + DBDTdll = (DBDTdll_POINTER) getFunctionPointer((char *) DBDTdll_NAME); + DBFL1dll = (DBFL1dll_POINTER) getFunctionPointer((char *) DBFL1dll_NAME); + DBFL2dll = (DBFL2dll_POINTER) getFunctionPointer((char *) DBFL2dll_NAME); + DDDPdll = (DDDPdll_POINTER) getFunctionPointer((char *) DDDPdll_NAME); + DDDTdll = (DDDTdll_POINTER) getFunctionPointer((char *) DDDTdll_NAME); + DEFLSHdll = (DEFLSHdll_POINTER) getFunctionPointer((char *) DEFLSHdll_NAME); + DHD1dll = (DHD1dll_POINTER) getFunctionPointer((char *) DHD1dll_NAME); + DHFLSHdll = (DHFLSHdll_POINTER) getFunctionPointer((char *) DHFLSHdll_NAME); + DIELECdll = (DIELECdll_POINTER) getFunctionPointer((char *) DIELECdll_NAME); + DOTFILLdll = (DOTFILLdll_POINTER) getFunctionPointer((char *) DOTFILLdll_NAME); + DPDD2dll = (DPDD2dll_POINTER) getFunctionPointer((char *) DPDD2dll_NAME); + DPDDKdll = (DPDDKdll_POINTER) getFunctionPointer((char *) DPDDKdll_NAME); + DPDDdll = (DPDDdll_POINTER) getFunctionPointer((char *) DPDDdll_NAME); + DPDTKdll = (DPDTKdll_POINTER) getFunctionPointer((char *) DPDTKdll_NAME); + DPDTdll = (DPDTdll_POINTER) getFunctionPointer((char *) DPDTdll_NAME); + DPTSATKdll = (DPTSATKdll_POINTER) getFunctionPointer((char *) DPTSATKdll_NAME); + DSFLSHdll = (DSFLSHdll_POINTER) getFunctionPointer((char *) DSFLSHdll_NAME); + ENTHALdll = (ENTHALdll_POINTER) getFunctionPointer((char *) ENTHALdll_NAME); + ENTROdll = (ENTROdll_POINTER) getFunctionPointer((char *) ENTROdll_NAME); + ESFLSHdll = (ESFLSHdll_POINTER) getFunctionPointer((char *) ESFLSHdll_NAME); + FGCTYdll = (FGCTYdll_POINTER) getFunctionPointer((char *) FGCTYdll_NAME); + FPVdll = (FPVdll_POINTER) getFunctionPointer((char *) FPVdll_NAME); + GERG04dll = (GERG04dll_POINTER) getFunctionPointer((char *) GERG04dll_NAME); + GETFIJdll = (GETFIJdll_POINTER) getFunctionPointer((char *) GETFIJdll_NAME); + GETKTVdll = (GETKTVdll_POINTER) getFunctionPointer((char *) GETKTVdll_NAME); + GIBBSdll = (GIBBSdll_POINTER) getFunctionPointer((char *) GIBBSdll_NAME); + HSFLSHdll = (HSFLSHdll_POINTER) getFunctionPointer((char *) HSFLSHdll_NAME); + INFOdll = (INFOdll_POINTER) getFunctionPointer((char *) INFOdll_NAME); + LIMITKdll = (LIMITKdll_POINTER) getFunctionPointer((char *) LIMITKdll_NAME); + LIMITSdll = (LIMITSdll_POINTER) getFunctionPointer((char *) LIMITSdll_NAME); + LIMITXdll = (LIMITXdll_POINTER) getFunctionPointer((char *) LIMITXdll_NAME); + MELTPdll = (MELTPdll_POINTER) getFunctionPointer((char *) MELTPdll_NAME); + MELTTdll = (MELTTdll_POINTER) getFunctionPointer((char *) MELTTdll_NAME); + MLTH2Odll = (MLTH2Odll_POINTER) getFunctionPointer((char *) MLTH2Odll_NAME); + NAMEdll = (NAMEdll_POINTER) getFunctionPointer((char *) NAMEdll_NAME); + PDFL1dll = (PDFL1dll_POINTER) getFunctionPointer((char *) PDFL1dll_NAME); + PDFLSHdll = (PDFLSHdll_POINTER) getFunctionPointer((char *) PDFLSHdll_NAME); + PEFLSHdll = (PEFLSHdll_POINTER) getFunctionPointer((char *) PEFLSHdll_NAME); + PHFL1dll = (PHFL1dll_POINTER) getFunctionPointer((char *) PHFL1dll_NAME); + PHFLSHdll = (PHFLSHdll_POINTER) getFunctionPointer((char *) PHFLSHdll_NAME); + PQFLSHdll = (PQFLSHdll_POINTER) getFunctionPointer((char *) PQFLSHdll_NAME); + PREOSdll = (PREOSdll_POINTER) getFunctionPointer((char *) PREOSdll_NAME); + PRESSdll = (PRESSdll_POINTER) getFunctionPointer((char *) PRESSdll_NAME); + PSFL1dll = (PSFL1dll_POINTER) getFunctionPointer((char *) PSFL1dll_NAME); + PSFLSHdll = (PSFLSHdll_POINTER) getFunctionPointer((char *) PSFLSHdll_NAME); + PUREFLDdll = (PUREFLDdll_POINTER) getFunctionPointer((char *) PUREFLDdll_NAME); + RESIDUALdll = (RESIDUALdll_POINTER) getFunctionPointer((char *) RESIDUALdll_NAME); + QMASSdll = (QMASSdll_POINTER) getFunctionPointer((char *) QMASSdll_NAME); + QMOLEdll = (QMOLEdll_POINTER) getFunctionPointer((char *) QMOLEdll_NAME); + SATDdll = (SATDdll_POINTER) getFunctionPointer((char *) SATDdll_NAME); + SATEdll = (SATEdll_POINTER) getFunctionPointer((char *) SATEdll_NAME); + SATHdll = (SATHdll_POINTER) getFunctionPointer((char *) SATHdll_NAME); + SATPdll = (SATPdll_POINTER) getFunctionPointer((char *) SATPdll_NAME); + SATSdll = (SATSdll_POINTER) getFunctionPointer((char *) SATSdll_NAME); + SATTdll = (SATTdll_POINTER) getFunctionPointer((char *) SATTdll_NAME); + SETAGAdll = (SETAGAdll_POINTER) getFunctionPointer((char *) SETAGAdll_NAME); + SETKTVdll = (SETKTVdll_POINTER) getFunctionPointer((char *) SETKTVdll_NAME); + SETMIXdll = (SETMIXdll_POINTER) getFunctionPointer((char *) SETMIXdll_NAME); + SETMODdll = (SETMODdll_POINTER) getFunctionPointer((char *) SETMODdll_NAME); + SETREFdll = (SETREFdll_POINTER) getFunctionPointer((char *) SETREFdll_NAME); + SETUPdll = (SETUPdll_POINTER) getFunctionPointer((char *) SETUPdll_NAME); +// SPECGRdll = (SPECGRdll_POINTER) getFunctionPointer((char *)SPECGRdll_NAME); // not in library + SUBLPdll = (SUBLPdll_POINTER) getFunctionPointer((char *) SUBLPdll_NAME); + SUBLTdll = (SUBLTdll_POINTER) getFunctionPointer((char *) SUBLTdll_NAME); + SURFTdll = (SURFTdll_POINTER) getFunctionPointer((char *) SURFTdll_NAME); + SURTENdll = (SURTENdll_POINTER) getFunctionPointer((char *) SURTENdll_NAME); + TDFLSHdll = (TDFLSHdll_POINTER) getFunctionPointer((char *) TDFLSHdll_NAME); + TEFLSHdll = (TEFLSHdll_POINTER) getFunctionPointer((char *) TEFLSHdll_NAME); + THERM0dll = (THERM0dll_POINTER) getFunctionPointer((char *) THERM0dll_NAME); + THERM2dll = (THERM2dll_POINTER) getFunctionPointer((char *) THERM2dll_NAME); + THERM3dll = (THERM3dll_POINTER) getFunctionPointer((char *) THERM3dll_NAME); + THERMdll = (THERMdll_POINTER) getFunctionPointer((char *) THERMdll_NAME); + THFLSHdll = (THFLSHdll_POINTER) getFunctionPointer((char *) THFLSHdll_NAME); + TPFLSHdll = (TPFLSHdll_POINTER) getFunctionPointer((char *) TPFLSHdll_NAME); + TPRHOdll = (TPRHOdll_POINTER) getFunctionPointer((char *) TPRHOdll_NAME); + TQFLSHdll = (TQFLSHdll_POINTER) getFunctionPointer((char *) TQFLSHdll_NAME); + TRNPRPdll = (TRNPRPdll_POINTER) getFunctionPointer((char *) TRNPRPdll_NAME); + TSFLSHdll = (TSFLSHdll_POINTER) getFunctionPointer((char *) TSFLSHdll_NAME); + VIRBdll = (VIRBdll_POINTER) getFunctionPointer((char *) VIRBdll_NAME); + VIRCdll = (VIRCdll_POINTER) getFunctionPointer((char *) VIRCdll_NAME); + WMOLdll = (WMOLdll_POINTER) getFunctionPointer((char *) WMOLdll_NAME); + XMASSdll = (XMASSdll_POINTER) getFunctionPointer((char *) XMASSdll_NAME); + XMOLEdll = (XMOLEdll_POINTER) getFunctionPointer((char *) XMOLEdll_NAME); + if (debug) printf ("Function pointers set to macro values.\n"); + return OK; + } + return FAIL; +} + +/* + * Make sure the library is loaded + * properly and set pointers. + */ +double initRefprop() { + if (RefpropdllInstance == NULL) { + if (debug) printf ("Library not loaded, trying to do so.\n"); + if (loadLibrary() != OK) { + printf("Refprop library %s cannot be loaded, make sure you ",libName); + printf("installed it properly.\n"); + return FAIL; + } + if (setFunctionPointers() != OK) { + printf("There was an error setting the REFPROP function pointers, "); + printf("check types and names in header file.\n"); + return FAIL; + } + return OK; + } else { + if (debug) printf ("Library loaded, not doing anything.\n"); + return OK; + } + return FAIL; +} + +/* + * Construct the fluid string with the full path + * from the simple names, needed for Linux version. + * Call setupdll if necessary to define the fluid + * or mixture for subsequent calls to flash routines. + */ +double setFluids(std::string sPath, std::string sFluids, char* error){ + // sPath: "/opt/refprop" or "C:\Program Files\Refprop" + // sFluids: "pentane|butane" or "air" + + if (initRefprop() != OK){ + std::cerr << "ERROR: library not loaded.\n"; + std::terminate(); + } + + long ierr=999; + char hf[refpropcharlength*ncmax]; + + std::string RefString; + std::string fdPath = std::string(sPath); + fdPath.append((char *)pathSep); + fdPath.append("fluids"); + fdPath.append((char *)pathSep); + + if (loadedFluids.compare(sFluids)) { // The fluid is not already loaded + std::vector components_split = strsplit(sFluids,'|');// Split into components + RefString.clear(); // Flush out fluid string + + // Build new fluid string + for (unsigned int j=0;jncmax){ + sprintf(error,"Too many components (More than %i)\n",ncmax); + return FAIL; + } + + // Prepare strings and call SETUP to initialise the program + strcpy(hf,RefString.c_str()); + char* hfm = (char*) calloc(refpropcharlength+8, sizeof(char)); + strcpy(hfm,fdPath.c_str()); + strcat(hfm,hfmix); + + //...Call SETUPdll to set the fluids + if (debug) { + printf ("Running SETUP...\n"); + printf ("No. of components: %li \n", lnc); + printf ("Fluid files: %s \n", RefString.c_str()); + printf ("Mixture file: %s \n", hfmix); + } + + SETUPdll(lnc, hf, hfm, hrf, ierr, error, + refpropcharlength*ncmax,refpropcharlength, + lengthofreference,errormessagelength); + free (hfm); + + if (ierr != 0) { + printf("REFPROP setup gives this error during SETUP:\n %s\n",error); + printf("Further information:\n %s\n",resolve_error("",ierr,error).c_str()); + return FAIL; + } else { //Copy the name of the loaded fluid + loadedFluids = std::string(sFluids); + int flush = flushConstants(); + if (debug) printf("Loading a new fluid, flushing constants: %i.\n",flush); + return OK; + } + } // Fluid was already loaded + if (debug) printf("Fluid was already loaded.\n"); + return OK; +} + + +bool isInput(std::string in1, std::string in2, std::string def){ + // if the first equals the first + if ( strCompare(in1, def.substr(0,1)) ) { + if ( strCompare(in2, def.substr(1,1)) ) return true; + } else if ( strCompare(in2, def.substr(0,1)) ) { + if ( strCompare(in1, def.substr(1,1)) ) return true; + } + return false; +} + +double getT_refprop(double t) { + // t--temperature [K] + return t*1.; +} + +double getP_refprop(double p) { + // p--pressure [kPa] + return p/1000.0; +} + +double getD_refprop(double d) { + // d--bulk molar density [mol/L] + return d/dwm; // kg/m3 = g/l / g/mol = mol/l +} + +double getE_refprop(double e) { + // e--internal energy [J/mol] + return e*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getH_refprop(double h) { + // h--enthalpy [J/mol] + return h*dwm/1000.; // J/kg * g/mol * kg/(1000g) = J/mol +} + +double getS_refprop(double s) { + // s--entropy [[J/mol-K] + return s*dwm/1000.; // J/(kg.K) * g/mol * kg/(1000g) = J/(mol.K) +} + +/* + * Convert to SI units + */ +double getT_modelica() { + // t--temperature [K] + return dt; +} + +double getP_modelica() { + // p--pressure [kPa] + return dp*1000.0; +} + +double getD_modelica() { + // d--bulk molar density [mol/L] + return dd*dwm; // mol/l * g/mol = g/l = kg/m3 +} + +double getE_modelica() { + // e--internal energy [J/mol] + return de/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getH_modelica() { + // h--enthalpy [J/mol] + return dh/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getS_modelica() { + // s--entropy [[J/mol-K] + return ds/dwm * 1000.0; // J/(mol.K) / g/mol * 1000g/kg = J/(kg.K) +} + +double getWM_modelica(){ + //molecular weight + return dwm/1000; +} + +double getDL_modelica(){ + //density of liquid phase + return ddl*dwliq; // mol/l * g/mol = g/l = kg/m3 +} + +double getDV_modelica(){ + //density of gaseous phase + return ddv*dwvap; // mol/l * g/mol = g/l = kg/m3 +} + +double getQ_modelica(){ + if (lnc>1 && abs(dqmol)<990) { // maintain special values + if (dwvap==noValue) WMOLdll(dxmolv,dwvap); + return dqmol*dwvap/dwm; + } else { + return dqmol; + } +} + +double getCV_modelica(){ + return dCv/dwm * 1000.0; +} + +double getCP_modelica(){ + return dCp/dwm * 1000.0; +} + +double getW_modelica(){ + //speed of sound + return dw; +} + +double getWML_modelica(){ + if (dwliq==noValue) WMOLdll(dxmoll,dwliq); + return dwliq/1000.; +} + +double getWMV_modelica(){ + if (dwvap==noValue) WMOLdll(dxmolv,dwvap); + return dwvap/1000.; +} + +//double* getXL_modelica(){ +// double dxlkg[ncmax]; +// XMASSdll(dxmoll,dxlkg,dwliq); +// return dxlkg; +//} +// +//double* getXV_modelica(){ +// double dxvkg[ncmax]; +// XMASSdll(dxmolv,dxvkg,dwvap); +// return dxvkg; +//} + +double getETA_modelica(){ + return deta/1e6; +} + +double getTCX_modelica(){ + return dtcx; +} + +double getHJT_modelica() { // isenthalpic Joule-Thompson coefficient [K/kPa]/1000Pa*kPa = K/Pa + return dhjt/1000; +} +//double* getZ_modelica() { // compressibility factor (= PV/RT) [dimensionless] +// return dZ; +//} +double getA_modelica() { // Helmholtz energy [J/mol] + return dA/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getG_modelica() { // Gibbs free energy [J/mol] + return dG/dwm * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getXKAPPA_modelica() { // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/kPa] /1000Pa*kPa = 1/Pa + return dxkappa / 1000. ; +} +double getBETA_modelica() { // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + return dbeta; +} +double getDPDD_modelica() { // derivative dP/drho [kPa-L/mol] * 1000Pa/kPa * mol/g = Pa.m3 / kg + return ddpdd * 1000. / dwm; +} +double getD2PDD2_modelica() { // derivative d^2P/drho^2 [kPa-L^2/mol^2] * 1000Pa/kPa * mol/g * mol/g = Pa m6 / kg2 + return dd2pdd2 * 1000. / dwm / dwm; +} +double getDPDT_modelica() { // derivative dP/dT [kPa/K] * 1000Pa/kPa = Pa/K + return ddpdt * 1000.; +} +double getDDDT_modelica() { // derivative drho/dT [mol/(L-K)] * g/mol = kg/m3 / K + return ddddt * dwm; +} +double getDDDP_modelica() { // derivative drho/dP [mol/(L-kPa)] + return ddddp*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +} +double getD2PDT2_modelica() { // derivative d2P/dT2 [kPa/K^2] * 1000Pa/kPa = Pa/K2 + return dd2pdt2 * 1000.; +} +double getD2PDTD_modelica() { // derivative d2P/dTd(rho) [J/mol-K] / g/mol * 1000g/kg = J/kg.K + return dd2pdtd/dwm*1000.; +} + + +double get_dhdt_d_modelica() { //dH/dT at constant density [J/(mol-K)] / g/mol * 1000g/kg = J/kg.K + return ddhdt_d/dwm*1000; +} +double get_dhdt_p_modelica() { //dH/dT at constant pressure [J/(mol-K)] + return ddhdt_p/dwm*1000; +} +double get_dhdd_t_modelica() { //dH/drho at constant temperature [(J/mol)/(mol/L)] * mol/g * 1000g/kg / g/mol = (J/kg) / (kg/m3) + return ddhdd_t /dwm*1000. / dwm; +} +double get_dhdd_p_modelica() { //dH/drho at constant pressure [(J/mol)/(mol/L)] + return ddhdd_p /dwm*1000. / dwm; +} +double get_dhdp_t_modelica() { //dH/dP at constant temperature [J/(mol-kPa)] /dwm*1000. / (1000Pa/kPa) = J/kg.Pa + return ddhdp_t / dwm; +} +double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] + return ddhdp_d / dwm; +} + +// Numerical derivatives +// Derivative of density with respect to enthalpy at constant pressure +double get_dddh_p_modelica(){ + return ddddh_p*dwm*dwm/1000.; // (mol/l * mol/J) * g/mol * g/mol * 1kg/1000g = kg/m3 * kg/J +} +// Derivative of density with respect to pressure at constant enthalpy +double get_dddp_h_modelica(){ + return ddddp_h*dwm/1000.; // mol/(l.kPa) * g/mol * 1kPa/1000Pa = kg/(m3.Pa) +} + + +/* + * Checks if the provided variables match the currently active + * state. Needs the current values of the state properties as + * well as the new ones. Additionally, the mole based composition + * has to be provided with the number of components. + * Changing the amount of components or the fluids itself should + * be covered by the flushing routines above. + */ +bool isState(double var1, double val1, double var2, double val2, double xmol[], long nc){ + if (debug) printf ("\nChecking state.\n"); + if (var1!=val1) return false; + if (var2!=val2) return false; + //if (lnc!=nc) return false; + // If we have a mixture, we need to check the composition. + if (nc>1) { + for ( int i = 0; i < nc; i++ ) { + if (dxmol[i]!=xmol[i]) return false; + } + } + if (debug) printf ("Going to return \"true\".\n"); + return true; +} + + +double getValue(std::string out) { + + if (debug) printf("\nChecking for %s \n",out.c_str()); + + if ( strCompare(out, "p") ) { + if (dp!=noValue) return getP_modelica(); + } else if ( strCompare(out, "t") ) { + if (dt!=noValue) return getT_modelica(); + } else if ( strCompare(out, "m") ) { + if (dwm!=noValue) return getWM_modelica(); + } else if ( strCompare(out, "d") ) { + if (dd!=noValue) return getD_modelica(); + } else if ( strCompare(out, "e") ) { + if (de!=noValue) return getE_modelica(); + } else if ( strCompare(out, "h") ) { + if (dh!=noValue) return getH_modelica(); + } else if ( strCompare(out, "s") ) { + if (ds!=noValue) return getS_modelica(); + } else if ( strCompare(out, "w") ) { + if (dw!=noValue) return getW_modelica(); + } else if ( strCompare(out, "v") ) { + if (deta!=noValue) return getETA_modelica(); + } else if ( strCompare(out, "l") ) { + if (dtcx!=noValue) return getTCX_modelica(); + } + return noValue; +} + +///* +// * Improvised derivative computing. These functions are called +// * after properties were calculated. Hence, we have density and +// * pressure available. REFPROP is formulated with explicit d and +// * T it should not take too much extra time. +// */ +//double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; +//double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; +//int setExtra(bool debug, long lerr, char* errormsg){ +// double rho,T; +// rho = getValue("d"); +// T = getValue("T"); +// if ((rho!=noValue)&&(T!=noValue)) { // call explicit function +// // get derivative of density with respect to pressure from Refprop library +// if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); +// THERM2dll (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); +//// deltaP = 1.; +//// pLow = dp - 0.5*deltaP; +//// pHigh = dp + 0.5*deltaP; +//// rhoLow = 0; +//// rhoHigh = 0; +//// //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); +//// PHFLSHdll(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); +//// PHFLSHdll(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +//// if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); +//// ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); +// +// // get derivative of density with respect to enthalpy numerically +// deltaH = 20.; +// hLow = dh - 0.5*deltaH; +// hHigh = dh + 0.5*deltaH; +// rhoLow = 0; +// rhoHigh = 0; +// //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); +// PHFLSHdll(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); +// PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); +// if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); +// ddddh = (rhoHigh-rhoLow) / (hHigh-hLow); +// } else { // We have a problem! +// printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); +// } +// return 0; +//} + +//int updateExtra(double *der, long lerr){ +//// c inputs: +//// c t--temperature [K] +//// c rho--molar density [mol/L] +//// c x--composition [array of mol frac] +//// c outputs: +//// c p--pressure [kPa] +//// c e--internal energy [J/mol] +//// c h--enthalpy [J/mol] +//// c s--entropy [J/mol-K] +//// c Cv--isochoric heat capacity [J/mol-K] +//// c Cp--isobaric heat capacity [J/mol-K] +//// c w--speed of sound [m/s] +//// c Z +//// c hjt +//// c A +//// c G +//// c xkappa +//// c beta +//// c dPdrho +//// c d2PdD2 +//// c dPT +//// c drhodT +//// c drhodP +//// c d2PT2 +//// c d2PdTD +//// c sparei--2 space holders for possible future properties +// +// +//// subroutine DHD1(t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d) +////c +////c compute partial derivatives of enthalpy w.r.t. t, p, or rho at constant +////c t, p, or rho as a function of temperature, density, and composition +////c +////c inputs: +////c t--temperature [K] +////c rho--molar density [mol/L] +////c x--composition [array of mol frac] +////c outputs: +////c get_dhdt_d_modelica(); --dH/dT at constant density [J/(mol-K)] +////c get_dhdt_p_modelica(); --dH/dT at constant pressure [J/(mol-K)] +////c get_dhdd_t_modelica(); --dH/drho at constant temperature [(J/mol)/(mol/L)] +////c get_dhdd_p_modelica(); --dH/drho at constant pressure [(J/mol)/(mol/L)] +////c get_dhdp_t_modelica(); --dH/dP at constant temperature [J/(mol-kPa)] +////c get_dhdp_d_modelica(); --dH/dP at constant density [J/(mol-kPa)] +// +//// double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, +//// ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, +//// + + +// +// +// +// +// getDDDH +// +// +// +// +//// THERM2dll (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); +// +// //ASSIGN VALUES TO RETURN ARRAY +// der[0] = lerr;//error code +// der[1] = getP_modelica(); //pressure in Pa +// der[2] = getT_modelica(); //Temperature in K +// der[3] = getWM_modelica(); //molecular weight +// der[4] = getD_modelica(); //density +// der[5] = getDL_modelica(); //density of liquid phase +// der[6] = getDV_modelica(); //density of liquid phase +// der[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) +// der[8] = getE_modelica(); //internal energy +// der[9] = getH_modelica(); //specific enthalpy +// der[10] = getS_modelica(); //specific entropy +// der[11] = getCV_modelica(); // heat capacity +// der[12] = getCP_modelica(); // heat capacity +// der[13] = getW_modelica(); //speed of sound +// der[14] = getDDDH_modelica(); //ddhp +// der[15] = getDDDP_modelica(); //ddph +// der[16] = getWML_modelica(); +// der[17] = getWMV_modelica(); +// +// double dxlkg[ncmax], dxvkg[ncmax]; +// +// +// return 0; +//} + + + +int updateDers(double *ders, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + ders[0] = lerr;//error code + ders[1] = getHJT_modelica(); // isenthalpic Joule-Thompson coefficient [K/Pa] + ders[2] = getA_modelica(); // Helmholtz energy [J/kg] + ders[3] = getG_modelica(); // Gibbs free energy [J/kg] + ders[4] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[5] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[6] = getDPDD_modelica(); // derivative dP/drho [Pa-m3/kg] + ders[7] = getD2PDD2_modelica(); // derivative d^2P/drho^2 [Pa-m6/kg2] + ders[8] = getDPDT_modelica(); // derivative dP/dT [Pa/K] + ders[9] = getDDDT_modelica(); // derivative drho/dT [kg/(m3-K)] + ders[10] = getDDDP_modelica(); // derivative drho/dP [kg/(m3-kPa)] + ders[11] = getD2PDT2_modelica(); // derivative d2P/dT2 [Pa/K2] + ders[12] = getD2PDTD_modelica(); // derivative d2P/dTd(rho) [J/kg-K] + ders[13] = get_dhdt_d_modelica(); // dH/dT at constant density [J/(kg-K)] + ders[14] = get_dhdt_p_modelica(); // dH/dT at constant pressure [J/(kg-K)] + ders[15] = get_dhdd_t_modelica(); // dH/drho at constant temperature [(J/kg) / (kg/m3)] + ders[16] = get_dhdd_p_modelica(); // dH/drho at constant pressure [(J/kg) / (kg/m3)] + ders[17] = get_dhdp_t_modelica(); // dH/dP at constant temperature [J/(kg-Pa)] + ders[18] = get_dhdp_d_modelica(); // dH/dP at constant density [J/(kg-Pa)] + ders[19] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + return 0; +} + +int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; + double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; + + if ((dd!=noValue)&&(dt!=noValue)) { + // call explicit functions in d and T + // get derivatives from Refprop library + if (debug) printf("Calling THERM2 with T=%f and rho=%f.\n",dt,dd); + THERM2dll (dt,dd,dxmol,spare5,spare6,spare9,spare10,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); + + // get derivatives of enthalpy + if (debug) printf("Calling DHD1 with T=%f and rho=%f.\n",dt,dd); + DHD1dll(dt,dd,dxmol,ddhdt_d,ddhdt_p,ddhdd_t,ddhdd_p,ddhdp_t,ddhdp_d); + + /* + * With the above values, the cyclic relation can be used to + * determine all necessary values. + * + * -1 = ddddp_ana * 1/(props.state.dhdp_rho) * props.state.dhdrho_p; + * ddddh_ana * props.state.dhdrho_p= 1; + * + * Below is a numerical approximation due to problems in the + * two-phase region. + */ + + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + ddddp_h = -1. * ddhdp_d / ddhdd_p; + ddddh_p = 1./ddhdd_p; + } else { // two-phase region, get derivative of density with respect to enthalpy numerically + if (debug) printf ("Using two-phase derivatives.\n"); + deltaP = 0.00005; // 0.05 Pascal difference + pLow = dp - 0.5*deltaP; + pHigh = dp + 0.5*deltaP; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); + PHFLSHdll(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); + PHFLSHdll(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); + ddddp_h = (rhoHigh-rhoLow) / (pHigh-pLow); + + // get derivative of density with respect to enthalpy numerically + deltaH = 0.05; // 0.05 Joule total difference + hLow = dh - 0.5*deltaH; + hHigh = dh + 0.5*deltaH; + rhoLow = 0; + rhoHigh = 0; + //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); + PHFLSHdll(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); + PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); + if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); + ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + } + + } else { // We have a problem! + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); + } + + switch(lerr){ + case 4: + sprintf(errormsg,"P=%f < 0",dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + default: + break; + } + return updateDers(ders, lerr); +} + +int updateTrns(double *trns, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + trns[0] = lerr;//error code + trns[1] = getETA_modelica(); // dynamic viscosity in Pa.s + trns[2] = getTCX_modelica(); // thermal conductivity in W/m.K + return 0; +} + +int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ + debug = false; + if (DEBUGMODE) debug = true; + long lerr = 0; + + if ((dd!=noValue)&&(dt!=noValue)) { + // call explicit functions in d and T + // compute transport properties + if (debug) printf("Getting transport properties from T=%f and rho=%f.\n",dt,dd); + TRNPRPdll(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); + if (debug) printf("Thermal conductivity is lambda=%f W/m.K.\n",dtcx); + if (debug) printf("Dynamic viscosity is eta=%fµPa.s.\n",deta); + + } else { // We have a problem! + printf("Derivatives and transport properties calculations called at the wrong time: rho=%f and T=%f\n",dd,dt); + } + + switch(lerr){ + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + default: + break; + } + return updateTrns(trns, lerr); +} + + +int updateProps(double *props, long lerr){ + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica(); //pressure in Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) + props[8] = getE_modelica(); //inner energy + props[9] = getH_modelica(); //specific enthalpy + props[10] = getS_modelica(); //specific entropy + props[11] = getCV_modelica(); + props[12] = getCP_modelica(); + props[13] = getW_modelica(); //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + + double dxlkg[ncmax], dxvkg[ncmax]; + + XMASSdll(dxmoll,dxlkg,dwliq); + XMASSdll(dxmolv,dxvkg,dwvap); + + for (int dim=0; dim1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %s: %f.\n",out.c_str(),result); + updateProps(props, lerr); + return result; + } + } + + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + // ( strCompare(Poco::Environment::osName(), "linux") ) + + // Set variables to input values + if ( strCompare(in1, in2) ) { + sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); + return -1; + } + + memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; + //dxmol = dxmoltmp; + dwm = dwmtmp; + + double dqkg; + for (int ii=1;ii<3;ii++){ + + if (ii==1) { + tmpVar = in1; + tmpValue = statevar1; + } else if (ii==2) { + tmpVar = in2; + tmpValue = statevar2; + } + + // loop through possible inputs + if ( strCompare(tmpVar, "p") ) { + dp = getP_refprop(tmpValue); + } else if ( strCompare(tmpVar, "T") ) { + dt = getT_refprop(tmpValue); + } else if ( strCompare(tmpVar, "s") ) { + ds = getS_refprop(tmpValue); + } else if ( strCompare(tmpVar, "h") ) { + dh = getH_refprop(tmpValue); + } else if ( strCompare(tmpVar, "d") ) { + dd = getD_refprop(tmpValue); + } else if ( strCompare(tmpVar, "q") ) { + dqkg = tmpValue; + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable %i: %s",ii ,tmpVar.c_str()); + return lerr; + } + + if (debug) printf("Checked input variable: %s\n",tmpVar.c_str()); + } + + if (lerr==0){ + if (isInput(in1,in2,std::string("tp"))){ +// if (phase==2){ //fluid state is known to be two phase +// TPFL2dll(dt,dp,dxmol,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); +// }else{ + if (debug) printf("Calling TPFLSH with %f and %f.\n",dt,dp); + TPFLSHdll(dt,dp,dxmol,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + //if (debug) printf("Getting dd: %f\n",dd); +// } + }else if (isInput(in1,in2,std::string("ph"))){ +// if (phase==1){ //fluid state is known to be single phase +// PHFL1(p,h,x,liqvap,T,d,ierr,herr,errormessagelength); +//// if (liqvap==1) dl=d; else dv=d; +// }else{ + if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,dh); + PHFLSHdll(dp,dh,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("pd"))){ + if (phase==1){ //fluid state is known to be single phase + PDFL1dll(dp,dd,dxmol,dt,lerr,errormsg,errormessagelength); + }else{ + if (debug) printf("Calling PDFLSH with %f and %f.\n",dp,dd); + PDFLSHdll(dp,dd,dxmol,dt,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + } + }else if (isInput(in1,in2,std::string("sp"))){ +/* if (phase==1){ //fluid state is known to be single phase + PSFL1(p,s,dxmol,kph,T,d,lerr,errormsg,errormessagelength); + if (liqvap==1) dl=d; else dv=d; + }else{*/ + if (debug) printf("Calling PSFLSH with %f and %f.\n",dp,ds); + PSFLSHdll(dp,ds,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("pq"))){ + if (debug) printf("Calling PQFLSH with %f and %f.\n",dp,dqkg); + PQFLSHdll(dp,dqkg,dxmol,kq,dt,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// strcat(errormsg,"Bin in PQ!"); + }else if (isInput(in1,in2,std::string("th"))){ +/* if (phase==1){ //fluid state is known to be single phase + THFL1(T,h,dxmol,Dmin,Dmax,d,lerr,errormsg,errormessagelength); + }else{*/ + long kr = 2; +/* kr--phase flag: 1 = input state is liquid + 2 = input state is vapor in equilibrium with liq + 3 = input state is liquid in equilibrium with solid + 4 = input state is vapor in equilibrium with solid */ + if (debug) printf("Calling THFLSH with %f and %f.\n",dt,dh); + THFLSHdll(dt,dh,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); +// } + }else if (isInput(in1,in2,std::string("td"))){ + if (debug) printf("Calling TDFLSH with %f and %f.\n",dt,dd); + TDFLSHdll(dt,dd,dxmol,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("ts"))){ + long kr = 2; + if (debug) printf("Calling TSFLSH with %f and %f.\n",dt,ds); + TSFLSHdll(dt,ds,dxmol,kr,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("tq"))){ + if (debug) printf("Calling TQFLSH with %f and %f.\n",dt,dqkg); + TQFLSHdll(dt,dqkg,dxmol,kq,dp,dd,ddl,ddv,dxmoll,dxmolv,de,dh,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("dh"))){ + switch(phase){ //fluid state is known to be single phase + case 1: + DHFL1dll(dd,dh,dxmol,dt,lerr,errormsg,errormessagelength); + break; + case 2: + DHFL2dll(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); + break; + default: + if (debug) printf("Calling DHFLSH with %f and %f.\n",dd,dh); + DHFLSHdll(dd,dh,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); + break; + } + }else if (isInput(in1,in2,std::string("hs"))){ + HSFLSHdll(dh,ds,dxmol,dt,dp,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,dCv,dCp,dw,lerr,errormsg,errormessagelength); + }else if (isInput(in1,in2,std::string("ds"))){ + switch(phase){ //fluid state is known to be single phase + case 1: + DSFL1dll(dd,ds,dxmol,dt,lerr,errormsg,errormessagelength); + break; + case 2: + DSFL2dll(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,lerr,errormsg,errormessagelength); + break; + default: + if (debug) printf("Calling DSFLSH with %f and %f.\n",dd,ds); + DSFLSHdll(dd,ds,dxmol,dt,dp,ddl,ddv,dxmoll,dxmolv,dqmol,de,dh,dCv,dCp,dw,lerr,errormsg,errormessagelength); + break; + } + }else + sprintf(errormsg,"Unknown combination of state variables! %s and %s", in1.c_str(), in2.c_str()); + } + + +// switch(tolower(what[0])){ //CHOOSE RETURN VARIABLE +// case 'v': //dynamic viscosity uPa.s +// case 'l': //thermal conductivity W/m.K +// TRNPRPdll(dt,dd,dxmol,deta,dtcx,lerr,errormsg,errormessagelength); +// break; +// } + + + switch(lerr){ + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 4: + sprintf(errormsg,"P=%f < 0",dp); + break; + case 5: + sprintf(errormsg,"T=%f and p=%f out of range",dt,dp); + break; + case 8: + sprintf(errormsg,"x out of range (component and/or sum < 0 or > 1):%s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"x=%s or T=%f out of range",printX(dxmol,lnc).c_str(),dt); + break; + case 12: + sprintf(errormsg,"x=%s out of range and P=%f < 0",printX(dxmol,lnc).c_str(),dp); + break; + case 13: + sprintf(errormsg,"x=%s, T=%f and p=%f out of range",printX(dxmol,lnc).c_str(),dt,dp); + break; + case 16: + strcpy(errormsg,"TPFLSH error: p>melting pressure"); + break; + case -31: + sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + break; + case -32: + sprintf(errormsg,"density d=%f out of range for conductivity",dd); + break; + case -33: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + break; + case -41: + sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + break; + case -42: + sprintf(errormsg,"density d=%f out of range for viscosity",dd); + break; + case -43: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + break; + case -51: + sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + break; + case -52: + sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + break; + case -53: + sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + break; + case 39: + sprintf(errormsg,"model not found for thermal conductivity"); + break; + case 49: + sprintf(errormsg,"model not found for viscosity"); + break; + case 50: + sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + break; + case 51: + sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + break; + case -58: + case -59: + sprintf(errormsg,"ECS model did not converge"); + break; + case 211: + sprintf(errormsg,"TPFLSH bubble point calculation did not converge: [SATTP error 1] iteration failed to converge"); + break; + case 239: + sprintf(errormsg,"THFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 248: + sprintf(errormsg,"DSFLSH error: Iteration did not converge with d=%f and s=%f",dd,ds); + break; + case 249: + sprintf(errormsg,"PHFLSH error: Input value of enthalpy (%f) is outside limits",dh); + break; + case 271: + sprintf(errormsg,"TQFLSH error: T=%f > Tcrit, T-q calculation not possible",dt); + break; + case 291: + sprintf(errormsg,"PQFLSH error: p=%f > pcrit, p-q calculation not possible",dt); + break; + default: + //strncpy(errormsg,errormsg,errormessagelength); + break; + } + + + updateProps(props, lerr); + + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + + outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + + + if ( strCompare(out, "p") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); + return getP_modelica(); + } else if ( strCompare(out, "t") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getT_modelica()); + return getT_modelica(); + } else if ( strCompare(out, "m") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getWML_modelica()); + return getWM_modelica(); + } else if ( strCompare(out, "d") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getD_modelica()); + return getD_modelica(); + } else if ( strCompare(out, "q") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getQ_modelica()); + return getQ_modelica(); + } else if ( strCompare(out, "e") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getE_modelica()); + return getE_modelica(); + } else if ( strCompare(out, "h") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getH_modelica()); + return getH_modelica(); + } else if ( strCompare(out, "s") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getS_modelica()); + return getS_modelica(); + } else if ( strCompare(out, "w") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getW_modelica()); + return getW_modelica(); + } else if ( strCompare(out, "v") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getETA_modelica()); + return getETA_modelica(); + } else if ( strCompare(out, "l") ) { + if (debug) printf("Returning %s = %f\n",out.c_str(),getTCX_modelica()); + return getTCX_modelica(); + } else { + return -1.0; + } + +} + + +//--------------------------------------------------------------------------- + + +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) +INPUT: + what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function + statevar: string of 1 variable out of p,T,h,s,d + fluidnames: string containing names of substances in mixtured separated by |, substance names are identical to those of *.fld-files in REFPROP program directory + statevarval: values of the variable specified in statevar + x: array containing the mass fractions of the components of the mixture + REFPROP_PATH: string defining the path of the refprop.dll +OUTPUT + return value: value of variable specified by the input variable what + props: Array containing all calculated values + errormsg: string containing error message +*/ + + + long lerr = 0; + + +// DEBUGMODE = 1; + if (DEBUGMODE) debug = true; + std::string out = std::string(what).substr(0,1); + std::string in1 = std::string(statevar_in).substr(0,1); + std::string fluids = std::string(fluidnames); + std::string rPath = std::string(REFPROP_PATH); + + + /* + * Call method to initialise the library and check for new fluids. + * Afterwards, the fluids have been processed and the constants might + * have been flushed. + */ + if (debug) printf("\nStarting function props_REFPROP to calculate %s.\n", out.c_str()); + + if (setFluids(rPath,fluids,errormsg) != OK) { + printf("Error initialising REFPROP: \"%s\"\n", errormsg); + return -FAIL; + } + + + /* + * Here should be the state checking to avoid unnecessary calculations. when + * working with mixtures, the constants also have to be flushed if the + * composition changes. + */ + bool knownState = false; // dummies to force recalculation + bool valueExists = false; + + if (!knownState) { + if (lnc>1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + } else { // We have calculated it before. + if (valueExists) { + if (debug) printf("Working with old state, returning value for %i: %f.\n",what[0],-1.0); + return -1.0; + } + } + + + /* + * If we get to this point, the requested value was not part of an earlier + * calculation and we have to proceed to determine it via the Refprop library. + */ + + // Convert mass-based composition to mole fractions and set molecular weight. + double* dxkg; + dxkg = x; + XMOLEdll(dxkg,dxmol,dwm); + // dwm = dwm / 1000; // from g/mol to kg/mol + + // loop through possible inputs + if ( strCompare(in1, "p") ) { + dp = getP_refprop(statevarval); + } else if ( strCompare(in1, "t") ) { + dt = getT_refprop(statevarval); + } else if ( strCompare(in1, "d") ) { + dd = getD_refprop(statevarval); + } else { + lerr = 2; + sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); + return lerr; + } + if (debug) printf("\nstatevar %s checked\n",in1.c_str()); + + long j=2; +/* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) +*/ + long kph = -1; +/* kph--flag specifying desired root for multi-valued inputs + has meaning only for water at temperatures close to its triple point + -1 = return middle root (between 0 and 4 C) + 1 = return highest temperature root (above 4 C) + 3 = return lowest temperature root (along freezing line) */ + if (lerr==0) { + if ( strCompare(in1, "t") ) { + SATTdll(dt,dxmol,j,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } else if ( strCompare(in1, "p") ) { + SATPdll(dp,dxmol,j,dt,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + switch(lerr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } + //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + } else if ( strCompare(in1, "d") ) { + SATDdll(dd,dxmol,j,kph,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + switch(lerr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } + } + + switch(lerr){ + case 0: + strcpy(errormsg,"Saturation routine successful"); + break; + case 1: + sprintf(errormsg,"T=%f < Tmin",dt); + break; + case 8: + sprintf(errormsg,"x out of range, %s",printX(dxmol,lnc).c_str()); + break; + case 9: + sprintf(errormsg,"T=%f and x=%s out of range",dt,printX(dxmol,lnc).c_str()); + break; + case 10: + strcpy(errormsg,"D and x out of range"); + break; + case 12: + strcpy(errormsg,"P and x out of range"); + break; + case 120: + strcpy(errormsg,"CRITP did not converge"); + break; + case 121: + strcpy(errormsg,"T > Tcrit"); + break; + case 122: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 123: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 124: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -125: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -126: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -127: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 128: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 140: + strcpy(errormsg,"CRITP did not converge"); + break; + case 141: + strcpy(errormsg,"P > Pcrit"); + break; + case 142: + strcpy(errormsg,"TPRHO-liquid did not converge (pure fluid)"); + break; + case 143: + strcpy(errormsg,"TPRHO-vapor did not converge (pure fluid)"); + break; + case 144: + strcpy(errormsg,"pure fluid iteration did not converge"); + break; + case -144: + strcpy(errormsg,"Raoult's law (mixture initial guess) did not converge"); + break; + case -145: + strcpy(errormsg,"TPRHO did not converge for parent ph (mix)"); + break; + case -146: + strcpy(errormsg,"TPRHO did not converge for incipient (mix)"); + break; + case -147: + strcpy(errormsg,"composition iteration did not converge"); + break; + case 148: + strcpy(errormsg,"mixture iteration did not converge"); + break; + case 160: + strcpy(errormsg,"CRITP did not converge"); + break; + case 161: + strcpy(errormsg,"SATD did not converge"); + break; + default: + //strncpy(errormsg,herr,errormessagelength); + break; + } + + //ASSIGN VALUES TO RETURN ARRAY + props[0] = lerr;//error code + props[1] = getP_modelica(); //pressure in kPa->Pa + props[2] = getT_modelica(); //Temperature in K + props[3] = getWM_modelica(); //molecular weight + props[4] = getD_modelica(); //density + props[5] = getDL_modelica(); //density of liquid phase + props[6] = getDV_modelica(); //density of liquid phase + props[7] = 0; + props[8] = 0; //inner energy + props[9] = 0; //specific enthalpy + props[10] = 0; //specific entropy + props[11] = 0; + props[12] = 0; + props[13] = 0; //speed of sound + props[14] = getWML_modelica(); + props[15] = getWMV_modelica(); + + double dxlkg[ncmax], dxvkg[ncmax]; + + XMASSdll(dxmoll,dxlkg,dwliq); + XMASSdll(dxmolv,dxvkg,dwvap); + + for (int ii=0;ii strsplit(std::string s, char del); +//std::string get_REFPROP_fluid_path(std::string rpPath); +//std::string resolve_error(std::string in1, long lerr, char* errormsg); +//bool load_REFPROP(char* error); + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + EXPCONV double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; + EXPCONV double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE); //declaration; +#if defined(__cplusplus) +} +#endif // __cplusplus +#endif /*REFPROP_WRAPPER*/ diff --git a/package.mo b/package.mo index 6ada16a..9285011 100644 --- a/package.mo +++ b/package.mo @@ -1,7 +1,9 @@ within ; package REFPROP2Modelica -// constant String REFPROP_PATH = "d:\\Program Files (x86)\\REFPROP\\"; - constant String REFPROP_PATH = "/opt/refprop/"; + constant String REFPROP_PATH = "C:\\Program Files\\REFPROP"; +// constant String REFPROP_PATH = "/opt/refprop"; + + annotation (version="0.2", uses(Modelica(version="3.2")), diff --git a/package.order b/package.order index 9f103ad..885596b 100644 --- a/package.order +++ b/package.order @@ -1,5 +1,5 @@ REFPROP_PATH Examples +Interfaces Media Testers -Interfaces From 32c485f139012441d214c8bfb96df879208ca212 Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 25 Jul 2013 10:41:41 +0200 Subject: [PATCH 29/57] Update readme.md Added link to releases --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 1a27569..bb69acc 100644 --- a/readme.md +++ b/readme.md @@ -2,13 +2,13 @@ This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. ## Installation Instructions -You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. +You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. You can get the latest release from https://github.com/jowr/REFPROP2Modelica/releases ### Windows Since I do not run Windows regularly, I am not able to test many things myself. Could you, dear Windows users, please provide me with feedback? -1. After downloading and unzipping, rename folder to `REFPROP2Modelica`. +1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. 2. Run `_wrapper\v0.7\Makefile.bat` from your Visual Studio console, tested with VS9.0 (2008). 3. Make sure to have the shared library `refprop.dll` available on your system. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; @@ -17,7 +17,7 @@ provide me with feedback? ### Linux For installing on a Linux machine, please follow these instructions -1. After downloading and unzipping, rename folder to `REFPROP2Modelica`. +1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. 2. Open a command prompt in `_wrapper/v0.7/`, then run `make all` and `sudo make install_static`. 3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; From 528a87f369be232c2fdea4dfa243d99b1119aa4e Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 25 Jul 2013 10:45:58 +0200 Subject: [PATCH 30/57] Update readme.md More description. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index bb69acc..474be47 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ #Welcome to REFPROP2Modelica! -This piece of software enables the user to access the Refprop fluid property database from within Modelica. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. +This piece of software enables the user to access the Refprop fluid property database from within Modelica. Even though the code base is not very mature yet, this package seems to be the only solution to access properties of mixtures from within Modelica on both Windows and Linux systems. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. ## Installation Instructions You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. You can get the latest release from https://github.com/jowr/REFPROP2Modelica/releases From e338fa307fa4a5df40932581f5b407e8890dce2d Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 25 Jul 2013 10:46:47 +0200 Subject: [PATCH 31/57] Update readme.md removed outdated folder references --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 474be47..e879837 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ Since I do not run Windows regularly, I am not able to test many things myself. provide me with feedback? 1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. -2. Run `_wrapper\v0.7\Makefile.bat` from your Visual Studio console, tested with VS9.0 (2008). +2. Run `_wrapper\Makefile.bat` from your Visual Studio console, tested with VS9.0 (2008). 3. Make sure to have the shared library `refprop.dll` available on your system. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; @@ -18,7 +18,7 @@ provide me with feedback? For installing on a Linux machine, please follow these instructions 1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. -2. Open a command prompt in `_wrapper/v0.7/`, then run `make all` and `sudo make install_static`. +2. Open a command prompt in `_wrapper`, then run `make all` and `sudo make install_static`. 3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; 5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. From 32e9d2578c27dbef1fe43ee733d11d693d20bb64 Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 25 Jul 2013 15:04:45 +0200 Subject: [PATCH 32/57] Update readme.md Included Anish's suggestions --- readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index e879837..f39198e 100644 --- a/readme.md +++ b/readme.md @@ -9,16 +9,17 @@ Since I do not run Windows regularly, I am not able to test many things myself. provide me with feedback? 1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. -2. Run `_wrapper\Makefile.bat` from your Visual Studio console, tested with VS9.0 (2008). -3. Make sure to have the shared library `refprop.dll` available on your system. -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; +2. Open `_wrapper\Makefile.bat` with a text editor and edit line 23 and 24 according to your system (Dymola 2013 FD01, Dymola 2014 or ...). +3. Run `_wrapper\Makefile.bat` from your Visual Studio console, tested with VS 2008 and VS 2010 Express. +4. Make sure to have the shared library `refprop.dll` available on your system. This can be done by going to (Right click)Computer > Properties > Advanced system settings > Environment Variables. In the bottom half of the window (called System variables), select 'Path' and click 'Edit...'. This will open a new window called Edit System Variable'. Add the REFPROP directory path with a leading semicolon at the end in 'Variable value'. This directory path could be, e.g., C:\Program Files\REFPROP\ or C:\Program Files (x86)\REFPROP depending on your operating system. +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; or constant String REFPROP_PATH = C:\\Program Files (x86)\\REFPROP\\ ### Linux For installing on a Linux machine, please follow these instructions 1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. -2. Open a command prompt in `_wrapper`, then run `make all` and `sudo make install_static`. +2. Open a command prompt in `_wrapper`, then run `make all` and `sudo make install`. 3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. 4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; 5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. From 550f97b8de7a514d1b19e7aa8ed7e85e6a87ed4c Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 24 Sep 2013 16:40:58 +0200 Subject: [PATCH 33/57] Update readme.md Small fixes --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index f39198e..4aafdc5 100644 --- a/readme.md +++ b/readme.md @@ -12,7 +12,7 @@ provide me with feedback? 2. Open `_wrapper\Makefile.bat` with a text editor and edit line 23 and 24 according to your system (Dymola 2013 FD01, Dymola 2014 or ...). 3. Run `_wrapper\Makefile.bat` from your Visual Studio console, tested with VS 2008 and VS 2010 Express. 4. Make sure to have the shared library `refprop.dll` available on your system. This can be done by going to (Right click)Computer > Properties > Advanced system settings > Environment Variables. In the bottom half of the window (called System variables), select 'Path' and click 'Edit...'. This will open a new window called Edit System Variable'. Add the REFPROP directory path with a leading semicolon at the end in 'Variable value'. This directory path could be, e.g., C:\Program Files\REFPROP\ or C:\Program Files (x86)\REFPROP depending on your operating system. -5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: constant String REFPROP_PATH = `C:\\Program Files\\REFPROP\\`; or constant String REFPROP_PATH = C:\\Program Files (x86)\\REFPROP\\ +5. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). Make sure you mask the backslashes. It should look something like: `constant String REFPROP_PATH = "C:\\Program Files\\REFPROP\\";` or `constant String REFPROP_PATH = "C:\\Program Files (x86)\\REFPROP\\";` ### Linux @@ -21,7 +21,7 @@ For installing on a Linux machine, please follow these instructions 1. After downloading, unpack and rename the folder to `REFPROP2Modelica`. 2. Open a command prompt in `_wrapper`, then run `make all` and `sudo make install`. 3. Make sure to have the shared library `librefprop.so` available on your system. You might want to check https://github.com/jowr/librefprop.so for details. -4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: constant String REFPROP_PATH = "/opt/refprop/"; +4. Set the path to the REFPROP program directory with the constant String REFPROP_PATH (at the beginning of the Modelica package). It should look something like: `constant String REFPROP_PATH = "/opt/refprop/";` 5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. 6. ... and finally to remove the files from your system, please use `sudo make uninstall`. From d28ec38d1e1bae1630ffc40f167847838709d078 Mon Sep 17 00:00:00 2001 From: jowr Date: Wed, 23 Oct 2013 08:56:49 +0200 Subject: [PATCH 34/57] added possibility to change EOS in refprop_wrapper.cpp --- Examples.mo | 7 - Media/{Pentane.mo => Pentane/package.mo} | 3 +- Media/Pentane/package.order | 0 Media/R410.mo | 4 + Media/R410mix.mo | 5 - Media/R410mix/package.mo | 4 + Media/R410mix/package.order | 0 Media/Water.mo | 5 - Media/Water/package.mo | 4 + Media/Water/package.order | 0 Media/package.order | 1 + Testers/PropsMixture.mo | 2 +- Testers/PropsMixtureNH3H2O.mo | 2 - Testers/PropsMixtureTwo.mo | 2 +- Testers/PropsPureSubstance.mo | 6 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 ----------------------- Testers/package.order | 1 - _wrapper/src/refprop_wrapper.cpp | 6 + package.mo | 28 +-- 19 files changed, 34 insertions(+), 332 deletions(-) delete mode 100644 Examples.mo rename Media/{Pentane.mo => Pentane/package.mo} (50%) create mode 100644 Media/Pentane/package.order create mode 100644 Media/R410.mo delete mode 100644 Media/R410mix.mo create mode 100644 Media/R410mix/package.mo create mode 100644 Media/R410mix/package.order delete mode 100644 Media/Water.mo create mode 100644 Media/Water/package.mo create mode 100644 Media/Water/package.order delete mode 100644 Testers/Water_MixtureTwoPhase_pT.mo diff --git a/Examples.mo b/Examples.mo deleted file mode 100644 index a40086b..0000000 --- a/Examples.mo +++ /dev/null @@ -1,7 +0,0 @@ -within REFPROP2Modelica; -package Examples "Demonstration of the usage of the library" -extends Modelica.Icons.ExamplesPackage; -annotation(preferedView="info", - __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", - "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); -end Examples; diff --git a/Media/Pentane.mo b/Media/Pentane/package.mo similarity index 50% rename from Media/Pentane.mo rename to Media/Pentane/package.mo index 22d21a6..c1a94c4 100644 --- a/Media/Pentane.mo +++ b/Media/Pentane/package.mo @@ -1,5 +1,4 @@ within REFPROP2Modelica.Media; package Pentane "Pentane from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"pentane"}); + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"pentane"}); end Pentane; diff --git a/Media/Pentane/package.order b/Media/Pentane/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/R410.mo b/Media/R410.mo new file mode 100644 index 0000000..102fd49 --- /dev/null +++ b/Media/R410.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package R410 "R410 defined as pseudo pure in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"R410"}); +end R410; diff --git a/Media/R410mix.mo b/Media/R410mix.mo deleted file mode 100644 index 1d03112..0000000 --- a/Media/R410mix.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package R410mix "R410 defined as mixture in REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); -end R410mix; diff --git a/Media/R410mix/package.mo b/Media/R410mix/package.mo new file mode 100644 index 0000000..b6965ed --- /dev/null +++ b/Media/R410mix/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"R32","R125"}, reference_X = {0.697615,0.302385}); +end R410mix; diff --git a/Media/R410mix/package.order b/Media/R410mix/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/Water.mo b/Media/Water.mo deleted file mode 100644 index 67db3b5..0000000 --- a/Media/Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Water "Water from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"water"}); -end Water; diff --git a/Media/Water/package.mo b/Media/Water/package.mo new file mode 100644 index 0000000..2242ce3 --- /dev/null +++ b/Media/Water/package.mo @@ -0,0 +1,4 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames = {"water"}); +end Water; diff --git a/Media/Water/package.order b/Media/Water/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Media/package.order b/Media/package.order index 400476d..453f582 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,3 +1,4 @@ Pentane R410mix +R410 Water diff --git a/Testers/PropsMixture.mo b/Testers/PropsMixture.mo index a97b8c6..f120c58 100644 --- a/Testers/PropsMixture.mo +++ b/Testers/PropsMixture.mo @@ -32,7 +32,7 @@ equation // props.state.x = 0.5; // props.Xi = {.5}; // props.X = {.1,.9}; - props.Xi = {.5}; + props.Xi = {0.5}; // d = props.d; //h = props.h; //h = Medium.dewEnthalpy(props.sat); diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index a6624c8..0292e7b 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -25,8 +25,6 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); - p = Medium.pressure(state); q = Medium.vapourQuality(state); - end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index 2bc5347..7b79646 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -11,5 +11,5 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {.5}; + props.Xi = {0.5}; end PropsMixtureTwo; diff --git a/Testers/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo index 94d9161..e23b4a8 100644 --- a/Testers/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -5,7 +5,7 @@ model PropsPureSubstance //package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); //package Medium = REFPROPMedium(final substanceNames={"ammonia"}); //package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); Medium.BaseProperties props; @@ -15,14 +15,14 @@ package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNam // Modelica.SIunits.SpecificEnthalpy h; // Modelica.SIunits.SpecificEntropy s; // Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); // Modelica.SIunits.MolarMass MM; Real q= Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; // Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); // Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); equation props.p = 1e5 "sine_p.y"; props.h = 0+time*722774; diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo deleted file mode 100644 index deb20fd..0000000 --- a/Testers/Water_MixtureTwoPhase_pT.mo +++ /dev/null @@ -1,286 +0,0 @@ -within REFPROP2Modelica.Testers; -package Water_MixtureTwoPhase_pT - "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( - final mediumName="TwoPhaseMixtureWater", - final substanceNames={"water"}, - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = BrineConstants); -// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - redeclare model extends BaseProperties "Base properties of medium" - Real GVF=q*d/d_g "gas void fraction"; - Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ - Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); - Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); - Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) - "(min=0,max=1) gas phase mass fraction"; - // Integer phase_out "calculated phase"; - //END no gas case - equation - u = h - p/d; - MM = M_H2O; - R = Modelica.Constants.R/MM; - //End GVF - //DENSITY - // q = vapourQuality(state); - d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); - // d = d_l/(1-q*(1-d_l/d_g)); - //End DENSITY - //ENTHALPY - h = specificEnthalpy_pTX(p,T,X); - /* - if (p_H2O>p) then - h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); - else - h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); - end if; - h_gas_dissolved = 0; - Delta_h_solution = solutionEnthalpy(T) - "TODO: gilt nur bei gesättigter Lösung"; -*/ - //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); - //End ENTHALPY - s=0 "TODO"; - state = ThermodynamicState( - p=p, - T=T, - X=X, - X_l=X, - h=h, - GVF=GVF, - q=q, - s=0, - d_g=d_g, - d_l=d_l, - d=d, - phase=0) "phase_out"; - sat.psat = p "TODO"; - sat.Tsat = T "saturationTemperature(p) TODO"; - sat.X = X; - annotation (Documentation(info=""), - Documentation(revisions=" - -")); - end BaseProperties; - - redeclare function specificEnthalpy_pTX - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - /* input MassFraction q "(min=0,max=1)"; - input Real y "molar fraction of gas in gas phase";*/ - // input Real[3] TP; - output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); - algorithm - // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); - annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); - end specificEnthalpy_pTX; - - redeclare function temperature_phX - "numerically inverts specificEnthalpy_liquid_pTX" - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); - algorithm - // Modelica.Utilities.Streams.print("temperature_phX"); - annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); - end temperature_phX; - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T(unit="K") "Temperature of medium"; - MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Density d(start=300) "density"; - Real GVF "Gas Void Fraction"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real q "vapor quality on a mass basis [mass vapor/total mass]"; - annotation (Documentation(info=" - -")); -end ThermodynamicState; - - redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" - algorithm - hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); - end dewEnthalpy; - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - algorithm - hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); - end bubbleEnthalpy; - - redeclare function extends saturationTemperature - algorithm - //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); - T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); - end saturationTemperature; - - redeclare function extends dynamicViscosity - algorithm - eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); - end dynamicViscosity; - -redeclare function extends specificEntropy "specific entropy of water" -algorithm - s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); -end specificEntropy; - -redeclare function specificEnthalpy_ps - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEnthalpy_ps; - -redeclare function extends setState_psX - "Return thermodynamic state of water as function of p and s" -algorithm - state := ThermodynamicState( - d=density_ps(p,s), - T=temperature_ps(p,s), - phase=0, - h=specificEnthalpy_ps(p,s), - p=p, - X=X, - s=s, - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_psX; - - redeclare function extends temperature "return temperature of ideal gas" - algorithm - T := state.T; - end temperature; - - redeclare function extends density "return density of ideal gas" - algorithm - d := state.d; - end density; - -redeclare function extends setState_pTX - "Return thermodynamic state of water as function of p and T" -algorithm - state := ThermodynamicState( - d=density_pT(p,T), - T=T, - phase=0, - h=specificEnthalpy_pTX(p,s), - p=p, - X=X, - s=specificEntropy_pT(p.T), - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_pTX; - -redeclare function specificEntropy_pTX - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy T "Specific entropy"; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy s "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEntropy_pTX; - - redeclare function extends thermalConductivity - "Thermal conductivity of water" - algorithm - lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( - state.d, - state.T, - state.p, - state.phase); - end thermalConductivity; - - redeclare function extends specificHeatCapacityCp - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); - else - cp := Modelica.Media.Water.IF97_Utilities.cp_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCp; - - redeclare function extends saturationPressure - algorithm - p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); - end saturationPressure; - - redeclare function extends specificHeatCapacityCv - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); - else - cv := Modelica.Media.Water.IF97_Utilities.cv_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCv; - - annotation (Documentation(info=" -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-Documentation is found in the packages. Installation directions are found in both REFPROP packages. -

-

Contact for original implementation:

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" + annotation(version = "0.2", uses(Modelica(version = "3.2")), Documentation(info=" +

Documentation is found in the packages. Installation directions are found in both REFPROP packages.

+

Contact for original implementation:

+

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

+


Contact for this version:

+

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

+", + revisions = " ")); end REFPROP2Modelica; From e323cd6d5fffd564f93e6cc3e352aec041200621 Mon Sep 17 00:00:00 2001 From: jowr Date: Mon, 25 Nov 2013 16:33:34 +0100 Subject: [PATCH 35/57] Unicode debug, new folder --- _wrapper/bin/refprop_library.h | 788 -------------------- _wrapper/cpptest/refpropwrappertest_new.cpp | 282 +++++++ _wrapper/src/refprop_wrapper.cpp | 10 +- 3 files changed, 287 insertions(+), 793 deletions(-) delete mode 100644 _wrapper/bin/refprop_library.h create mode 100644 _wrapper/cpptest/refpropwrappertest_new.cpp diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h deleted file mode 100644 index 5231ae8..0000000 --- a/_wrapper/bin/refprop_library.h +++ /dev/null @@ -1,788 +0,0 @@ - -#ifndef REFPROP_LIB_H -#define REFPROP_LIB_H - -/* -// The idea here is to have a common header for Windows -// and gcc-like systems. The Windows branch should cover the -// functions provided by the .dll and the gcc part covers -// the compiled .so/.dym file. Name changes caused by gfortran -// are respected and should be accounted for. -*/ -#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) -# define __ISWINDOWS__ -# include -# define _CRT_SECURE_NO_WARNINGS -#elif __APPLE__ -# define __ISAPPLE__ -#elif __linux -# define __ISLINUX__ -#endif - -// Do some manual changes to the function names -// if needed, uses CoolProp platform detection. -#if defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV __stdcall -// Do not redefine function names for the shared library, -// in this case it is the REFPROP.dll and no special -// names are needed. Macros still need a value for the -// name function used below. -# define RPVersion RPVersion -# define SETPATHdll SETPATHdll -# define ABFL1dll ABFL1dll -# define ABFL2dll ABFL2dll -# define ACTVYdll ACTVYdll -# define AGdll AGdll -# define CCRITdll CCRITdll -# define CP0dll CP0dll -# define CRITPdll CRITPdll -# define CSATKdll CSATKdll -# define CV2PKdll CV2PKdll -# define CVCPKdll CVCPKdll -# define CVCPdll CVCPdll -# define DBDTdll DBDTdll -# define DBFL1dll DBFL1dll -# define DBFL2dll DBFL2dll -# define DDDPdll DDDPdll -# define DDDTdll DDDTdll -# define DEFLSHdll DEFLSHdll -# define DHD1dll DHD1dll -# define DHFL1dll DHFL1dll -# define DHFL2dll DHFL2dll -# define DHFLSHdll DHFLSHdll -# define DIELECdll DIELECdll -# define DOTFILLdll DOTFILLdll -# define DPDD2dll DPDD2dll -# define DPDDKdll DPDDKdll -# define DPDDdll DPDDdll -# define DPDTKdll DPDTKdll -# define DPDTdll DPDTdll -# define DPTSATKdll DPTSATKdll -# define DSFLSHdll DSFLSHdll -# define DSFL1dll DSFL1dll -# define DSFL2dll DSFL2dll -# define ENTHALdll ENTHALdll -# define ENTROdll ENTROdll -# define ESFLSHdll ESFLSHdll -# define FGCTYdll FGCTYdll -# define FPVdll FPVdll -# define GERG04dll GERG04dll -# define GETFIJdll GETFIJdll -# define GETKTVdll GETKTVdll -# define GIBBSdll GIBBSdll -# define HSFLSHdll HSFLSHdll -# define INFOdll INFOdll -# define LIMITKdll LIMITKdll -# define LIMITSdll LIMITSdll -# define LIMITXdll LIMITXdll -# define MELTPdll MELTPdll -# define MELTTdll MELTTdll -# define MLTH2Odll MLTH2Odll -# define NAMEdll NAMEdll -# define PDFL1dll PDFL1dll -# define PDFLSHdll PDFLSHdll -# define PEFLSHdll PEFLSHdll -# define PHFL1dll PHFL1dll -# define PHFLSHdll PHFLSHdll -# define PQFLSHdll PQFLSHdll -# define PREOSdll PREOSdll -# define PRESSdll PRESSdll -# define PSFL1dll PSFL1dll -# define PSFLSHdll PSFLSHdll -# define PUREFLDdll PUREFLDdll -# define QMASSdll QMASSdll -# define QMOLEdll QMOLEdll -# define RESIDUALdll RESIDUALdll -# define SATDdll SATDdll -# define SATEdll SATEdll -# define SATHdll SATHdll -# define SATPdll SATPdll -# define SATSdll SATSdll -# define SATTdll SATTdll -# define SETAGAdll SETAGAdll -# define SETKTVdll SETKTVdll -# define SETMIXdll SETMIXdll -# define SETMODdll SETMODdll -# define SETREFdll SETREFdll -# define SETUPdll SETUPdll -//# define SPECGRdll SPECGRdll // not found in library -# define SUBLPdll SUBLPdll -# define SUBLTdll SUBLTdll -# define SURFTdll SURFTdll -# define SURTENdll SURTENdll -# define TDFLSHdll TDFLSHdll -# define TEFLSHdll TEFLSHdll -# define THERM0dll THERM0dll -# define THERM2dll THERM2dll -# define THERM3dll THERM3dll -# define THERMdll THERMdll -# define THFLSHdll THFLSHdll -# define TPFLSHdll TPFLSHdll -# define TPFL2dll TPFL2dll -# define TPRHOdll TPRHOdll -# define TQFLSHdll TQFLSHdll -# define TRNPRPdll TRNPRPdll -# define TSFLSHdll TSFLSHdll -# define VIRBdll VIRBdll -# define VIRCdll VIRCdll -# define WMOLdll WMOLdll -# define XMASSdll XMASSdll -# define XMOLEdll XMOLEdll -#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV -// Define function names for the shared library, -// in this case it is the librefprop.so and the -// names might change on some systems during -// the compilation of the Fortran files. -// Possible other branches for this code could be: -// # if !defined(_AIX) -// # if !defined(__hpux) -// # if defined( _CRAY -// However, I cannot test that and therefore do not include it. -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define RESIDUALdll residualdll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -//# define SPECGRdll specgrdll_ // not found in library -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -#else // #elif defined(__ISLINUX__) -// Set some dummy names for the compiler -# define CALLCONV -# define RPVersion NOTAVAILABLE -# define SETPATHdll setpathdll -# define ABFL1dll abfl1dll -# define ABFL2dll abfl2dll -# define ACTVYdll actvydll -# define AGdll agdll -# define CCRITdll ccritdll -# define CP0dll cp0dll -# define CRITPdll critpdll -# define CSATKdll csatkdll -# define CV2PKdll cv2pkdll -# define CVCPKdll cvcpkdll -# define CVCPdll cvcpdll -# define DBDTdll dbdtdll -# define DBFL1dll dbfl1dll -# define DBFL2dll dbfl2dll -# define DDDPdll dddpdll -# define DDDTdll dddtdll -# define DEFLSHdll deflshdll -# define DHD1dll dhd1dll -# define DHFL1dll dhfl1dll -# define DHFL2dll dhfl2dll -# define DHFLSHdll dhflshdll -# define DIELECdll dielecdll -# define DOTFILLdll dotfilldll -# define DPDD2dll dpdd2dll -# define DPDDKdll dpddkdll -# define DPDDdll dpdddll -# define DPDTKdll dpdtkdll -# define DPDTdll dpdtdll -# define DPTSATKdll dptsatkdll -# define DSFLSHdll dsflshdll -# define DSFL1dll dsfl1dll -# define DSFL2dll dsfl2dll -# define ENTHALdll enthaldll -# define ENTROdll entrodll -# define ESFLSHdll esflshdll -# define FGCTYdll fgctydll -# define FPVdll fpvdll -# define GERG04dll gerg04dll -# define GETFIJdll getfijdll -# define GETKTVdll getktvdll -# define GIBBSdll gibbsdll -# define HSFLSHdll hsflshdll -# define INFOdll infodll -# define LIMITKdll limitkdll -# define LIMITSdll limitsdll -# define LIMITXdll limitxdll -# define MELTPdll meltpdll -# define MELTTdll melttdll -# define MLTH2Odll mlth2odll -# define NAMEdll namedll -# define PDFL1dll pdfl1dll -# define PDFLSHdll pdflshdll -# define PEFLSHdll peflshdll -# define PHFL1dll phfl1dll -# define PHFLSHdll phflshdll -# define PQFLSHdll pqflshdll -# define PREOSdll preosdll -# define PRESSdll pressdll -# define PSFL1dll psfl1dll -# define PSFLSHdll psflshdll -# define PUREFLDdll pureflddll -# define QMASSdll qmassdll -# define QMOLEdll qmoledll -# define RESIDUALdll residualdll -# define SATDdll satddll -# define SATEdll satedll -# define SATHdll sathdll -# define SATPdll satpdll -# define SATSdll satsdll -# define SATTdll sattdll -# define SETAGAdll setagadll -# define SETKTVdll setktvdll -# define SETMIXdll setmixdll -# define SETMODdll setmoddll -# define SETREFdll setrefdll -# define SETUPdll setupdll -//# define SPECGRdll specgrdll // not found in library -# define SUBLPdll sublpdll -# define SUBLTdll subltdll -# define SURFTdll surftdll -# define SURTENdll surtendll -# define TDFLSHdll tdflshdll -# define TEFLSHdll teflshdll -# define THERM0dll therm0dll -# define THERM2dll therm2dll -# define THERM3dll therm3dll -# define THERMdll thermdll -# define THFLSHdll thflshdll -# define TPFLSHdll tpflshdll -# define TPFL2dll tpfl2dll -# define TPRHOdll tprhodll -# define TQFLSHdll tqflshdll -# define TRNPRPdll trnprpdll -# define TSFLSHdll tsflshdll -# define VIRBdll virbdll -# define VIRCdll vircdll -# define WMOLdll wmoldll -# define XMASSdll xmassdll -# define XMOLEdll xmoledll -#endif // else branch -// -// -// Only continue if function names have been defined. -// We might want to include some more tests here... -#if defined(RPVersion) -// define new macros for function names -// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value -#include -#include -#define STR_VALUE(arg) #arg -#define FUNCTION_NAME(name) STR_VALUE(name) -// -// Prepare the strings to be used by the functions that -// handle the library later on. -#define RPVersion_NAME FUNCTION_NAME(RPVersion) -#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) -#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) -#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) -#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) -#define AGdll_NAME FUNCTION_NAME(AGdll) -#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) -#define CP0dll_NAME FUNCTION_NAME(CP0dll) -#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) -#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) -#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) -#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) -#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) -#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) -#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) -#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) -#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) -#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) -#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) -#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) -#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) -#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) -#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) -#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) -#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) -#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) -#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) -#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) -#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) -#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) -#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) -#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) -#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) -#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) -#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) -#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) -#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) -#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) -#define FPVdll_NAME FUNCTION_NAME(FPVdll) -#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) -#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) -#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) -#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) -#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) -#define INFOdll_NAME FUNCTION_NAME(INFOdll) -#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) -#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) -#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) -#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) -#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) -#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) -#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) -#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) -#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) -#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) -#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) -#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) -#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) -#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) -#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) -#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) -#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) -#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) -#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) -#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) -#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) -#define SATDdll_NAME FUNCTION_NAME(SATDdll) -#define SATEdll_NAME FUNCTION_NAME(SATEdll) -#define SATHdll_NAME FUNCTION_NAME(SATHdll) -#define SATPdll_NAME FUNCTION_NAME(SATPdll) -#define SATSdll_NAME FUNCTION_NAME(SATSdll) -#define SATTdll_NAME FUNCTION_NAME(SATTdll) -#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) -#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) -#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) -#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) -#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) -#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) -//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library -#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) -#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) -#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) -#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) -#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) -#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) -#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) -#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) -#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) -#define THERMdll_NAME FUNCTION_NAME(THERMdll) -#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) -#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) -#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) -#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) -#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) -#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) -#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) -#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) -#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) -#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) -#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) -#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) -// -// I'll try to follow this example from: -// http://www.gershnik.com/tips/cpp.asp -// function type: typedef void [compiler stuff] func_t(int, float); -// function declaration: func_t func; -// pointer type: typedef func_t * func_ptr; -#if defined(__cplusplus) -extern "C" { -#endif - typedef void (CALLCONV RPVersion_TYPE)( char* ); - typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); - // - typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); - typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); - typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); - typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); - typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); - typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); - typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); - typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); - typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); - typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PREOSdll_TYPE)(long &); - typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PUREFLDdll_TYPE)(long &); - typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); - typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); - typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); - typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); - typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); - typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); - typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); - typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); -// -// Disabled because we prefer pointers here! -// // Declare the functions for direct access, -// RPVersion_TYPE RPVersion; -// SETPATHdll_TYPE SETPATHdll; -// ABFL1dll_TYPE ABFL1dll; -// ABFL2dll_TYPE ABFL2dll; -// ACTVYdll_TYPE ACTVYdll; -// AGdll_TYPE AGdll; -// CCRITdll_TYPE CCRITdll; -// CP0dll_TYPE CP0dll; -// CRITPdll_TYPE CRITPdll; -// CSATKdll_TYPE CSATKdll; -// CV2PKdll_TYPE CV2PKdll; -// CVCPKdll_TYPE CVCPKdll; -// CVCPdll_TYPE CVCPdll; -// DBDTdll_TYPE DBDTdll; -// DBFL1dll_TYPE DBFL1dll; -// DBFL2dll_TYPE DBFL2dll; -// DDDPdll_TYPE DDDPdll; -// DDDTdll_TYPE DDDTdll; -// DEFLSHdll_TYPE DEFLSHdll; -// DHD1dll_TYPE DHD1dll; -// DHFLSHdll_TYPE DHFLSHdll; -// DHFL1dll_TYPE DHFL1dll; -// DHFL2dll_TYPE DHFL2dll; -// DIELECdll_TYPE DIELECdll; -// DOTFILLdll_TYPE DOTFILLdll; -// DPDD2dll_TYPE DPDD2dll; -// DPDDKdll_TYPE DPDDKdll; -// DPDDdll_TYPE DPDDdll; -// DPDTKdll_TYPE DPDTKdll; -// DPDTdll_TYPE DPDTdll; -// DPTSATKdll_TYPE DPTSATKdll; -// DSFLSHdll_TYPE DSFLSHdll; -// DSFL1dll_TYPE DSFL1dll; -// DSFL2dll_TYPE DSFL2dll; -// ENTHALdll_TYPE ENTHALdll; -// ENTROdll_TYPE ENTROdll; -// ESFLSHdll_TYPE ESFLSHdll; -// FGCTYdll_TYPE FGCTYdll; -// FPVdll_TYPE FPVdll; -// GERG04dll_TYPE GERG04dll; -// GETFIJdll_TYPE GETFIJdll; -// GETKTVdll_TYPE GETKTVdll; -// GIBBSdll_TYPE GIBBSdll; -// HSFLSHdll_TYPE HSFLSHdll; -// INFOdll_TYPE INFOdll; -// LIMITKdll_TYPE LIMITKdll; -// LIMITSdll_TYPE LIMITSdll; -// LIMITXdll_TYPE LIMITXdll; -// MELTPdll_TYPE MELTPdll; -// MELTTdll_TYPE MELTTdll; -// MLTH2Odll_TYPE MLTH2Odll; -// NAMEdll_TYPE NAMEdll; -// PDFL1dll_TYPE PDFL1dll; -// PDFLSHdll_TYPE PDFLSHdll; -// PEFLSHdll_TYPE PEFLSHdll; -// PHFL1dll_TYPE PHFL1dll; -// PHFLSHdll_TYPE PHFLSHdll; -// PQFLSHdll_TYPE PQFLSHdll; -// PREOSdll_TYPE PREOSdll; -// PRESSdll_TYPE PRESSdll; -// PSFL1dll_TYPE PSFL1dll; -// PSFLSHdll_TYPE PSFLSHdll; -// PUREFLDdll_TYPE PUREFLDdll; -// QMASSdll_TYPE QMASSdll; -// QMOLEdll_TYPE QMOLEdll; -// SATDdll_TYPE SATDdll; -// SATEdll_TYPE SATEdll; -// SATHdll_TYPE SATHdll; -// SATPdll_TYPE SATPdll; -// SATSdll_TYPE SATSdll; -// SATTdll_TYPE SATTdll; -// SETAGAdll_TYPE SETAGAdll; -// SETKTVdll_TYPE SETKTVdll; -// SETMIXdll_TYPE SETMIXdll; -// SETMODdll_TYPE SETMODdll; -// SETREFdll_TYPE SETREFdll; -// SETUPdll_TYPE SETUPdll; -//// SPECGRdll_TYPE SPECGRdll; // not found in library -// SUBLPdll_TYPE SUBLPdll; -// SUBLTdll_TYPE SUBLTdll; -// SURFTdll_TYPE SURFTdll; -// SURTENdll_TYPE SURTENdll; -// TDFLSHdll_TYPE TDFLSHdll; -// TEFLSHdll_TYPE TEFLSHdll; -// THERM0dll_TYPE THERM0dll; -// THERM2dll_TYPE THERM2dll; -// THERM3dll_TYPE THERM3dll; -// THERMdll_TYPE THERMdll; -// THFLSHdll_TYPE THFLSHdll; -// TPFLSHdll_TYPE TPFLSHdll; -// TPFL2dll_TYPE TPFL2dll; -// TPRHOdll_TYPE TPRHOdll; -// TQFLSHdll_TYPE TQFLSHdll; -// TRNPRPdll_TYPE TRNPRPdll; -// TSFLSHdll_TYPE TSFLSHdll; -// VIRBdll_TYPE VIRBdll; -// VIRCdll_TYPE VIRCdll; -// WMOLdll_TYPE WMOLdll; -// XMASSdll_TYPE XMASSdll; -// XMOLEdll_TYPE XMOLEdll; - // - // Define explicit function pointers - typedef RPVersion_TYPE * RPVersion_POINTER; - typedef SETPATHdll_TYPE * SETPATHdll_POINTER; - typedef ABFL1dll_TYPE * ABFL1dll_POINTER; - typedef ABFL2dll_TYPE * ABFL2dll_POINTER; - typedef ACTVYdll_TYPE * ACTVYdll_POINTER; - typedef AGdll_TYPE * AGdll_POINTER; - typedef CCRITdll_TYPE * CCRITdll_POINTER; - typedef CP0dll_TYPE * CP0dll_POINTER; - typedef CRITPdll_TYPE * CRITPdll_POINTER; - typedef CSATKdll_TYPE * CSATKdll_POINTER; - typedef CV2PKdll_TYPE * CV2PKdll_POINTER; - typedef CVCPKdll_TYPE * CVCPKdll_POINTER; - typedef CVCPdll_TYPE * CVCPdll_POINTER; - typedef DBDTdll_TYPE * DBDTdll_POINTER; - typedef DBFL1dll_TYPE * DBFL1dll_POINTER; - typedef DBFL2dll_TYPE * DBFL2dll_POINTER; - typedef DDDPdll_TYPE * DDDPdll_POINTER; - typedef DDDTdll_TYPE * DDDTdll_POINTER; - typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; - typedef DHD1dll_TYPE * DHD1dll_POINTER; - typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; - typedef DHFL1dll_TYPE * DHFL1dll_POINTER; - typedef DHFL2dll_TYPE * DHFL2dll_POINTER; - typedef DIELECdll_TYPE * DIELECdll_POINTER; - typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; - typedef DPDD2dll_TYPE * DPDD2dll_POINTER; - typedef DPDDKdll_TYPE * DPDDKdll_POINTER; - typedef DPDDdll_TYPE * DPDDdll_POINTER; - typedef DPDTKdll_TYPE * DPDTKdll_POINTER; - typedef DPDTdll_TYPE * DPDTdll_POINTER; - typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; - typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; - typedef DSFL1dll_TYPE * DSFL1dll_POINTER; - typedef DSFL2dll_TYPE * DSFL2dll_POINTER; - typedef ENTHALdll_TYPE * ENTHALdll_POINTER; - typedef ENTROdll_TYPE * ENTROdll_POINTER; - typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; - typedef FGCTYdll_TYPE * FGCTYdll_POINTER; - typedef FPVdll_TYPE * FPVdll_POINTER; - typedef GERG04dll_TYPE * GERG04dll_POINTER; - typedef GETFIJdll_TYPE * GETFIJdll_POINTER; - typedef GETKTVdll_TYPE * GETKTVdll_POINTER; - typedef GIBBSdll_TYPE * GIBBSdll_POINTER; - typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; - typedef INFOdll_TYPE * INFOdll_POINTER; - typedef LIMITKdll_TYPE * LIMITKdll_POINTER; - typedef LIMITSdll_TYPE * LIMITSdll_POINTER; - typedef LIMITXdll_TYPE * LIMITXdll_POINTER; - typedef MELTPdll_TYPE * MELTPdll_POINTER; - typedef MELTTdll_TYPE * MELTTdll_POINTER; - typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; - typedef NAMEdll_TYPE * NAMEdll_POINTER; - typedef PDFL1dll_TYPE * PDFL1dll_POINTER; - typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; - typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; - typedef PHFL1dll_TYPE * PHFL1dll_POINTER; - typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; - typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; - typedef PREOSdll_TYPE * PREOSdll_POINTER; - typedef PRESSdll_TYPE * PRESSdll_POINTER; - typedef PSFL1dll_TYPE * PSFL1dll_POINTER; - typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; - typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; - typedef QMASSdll_TYPE * QMASSdll_POINTER; - typedef QMOLEdll_TYPE * QMOLEdll_POINTER; - typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; - typedef SATDdll_TYPE * SATDdll_POINTER; - typedef SATEdll_TYPE * SATEdll_POINTER; - typedef SATHdll_TYPE * SATHdll_POINTER; - typedef SATPdll_TYPE * SATPdll_POINTER; - typedef SATSdll_TYPE * SATSdll_POINTER; - typedef SATTdll_TYPE * SATTdll_POINTER; - typedef SETAGAdll_TYPE * SETAGAdll_POINTER; - typedef SETKTVdll_TYPE * SETKTVdll_POINTER; - typedef SETMIXdll_TYPE * SETMIXdll_POINTER; - typedef SETMODdll_TYPE * SETMODdll_POINTER; - typedef SETREFdll_TYPE * SETREFdll_POINTER; - typedef SETUPdll_TYPE * SETUPdll_POINTER; -// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library - typedef SUBLPdll_TYPE * SUBLPdll_POINTER; - typedef SUBLTdll_TYPE * SUBLTdll_POINTER; - typedef SURFTdll_TYPE * SURFTdll_POINTER; - typedef SURTENdll_TYPE * SURTENdll_POINTER; - typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; - typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; - typedef THERM0dll_TYPE * THERM0dll_POINTER; - typedef THERM2dll_TYPE * THERM2dll_POINTER; - typedef THERM3dll_TYPE * THERM3dll_POINTER; - typedef THERMdll_TYPE * THERMdll_POINTER; - typedef THFLSHdll_TYPE * THFLSHdll_POINTER; - typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; - typedef TPFL2dll_TYPE * TPFL2dll_POINTER; - typedef TPRHOdll_TYPE * TPRHOdll_POINTER; - typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; - typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; - typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; - typedef VIRBdll_TYPE * VIRBdll_POINTER; - typedef VIRCdll_TYPE * VIRCdll_POINTER; - typedef WMOLdll_TYPE * WMOLdll_POINTER; - typedef XMASSdll_TYPE * XMASSdll_POINTER; - typedef XMOLEdll_TYPE * XMOLEdll_POINTER; -#if defined(__cplusplus) -} // extern "C" -#endif // __cplusplus -#endif // defined(RPversion) -#endif // REFPROP_LIB_H diff --git a/_wrapper/cpptest/refpropwrappertest_new.cpp b/_wrapper/cpptest/refpropwrappertest_new.cpp new file mode 100644 index 0000000..f904c7b --- /dev/null +++ b/_wrapper/cpptest/refpropwrappertest_new.cpp @@ -0,0 +1,282 @@ +#include +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;i Date: Mon, 25 Nov 2013 17:21:08 +0100 Subject: [PATCH 36/57] added a cpp file to use the wrapper --- _wrapper/cpptest/cpp_wrapped.cpp | 135 ++++++++++ _wrapper/cpptest/refpropwrappertest_new.cpp | 282 -------------------- 2 files changed, 135 insertions(+), 282 deletions(-) create mode 100644 _wrapper/cpptest/cpp_wrapped.cpp delete mode 100644 _wrapper/cpptest/refpropwrappertest_new.cpp diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp new file mode 100644 index 0000000..6f523e5 --- /dev/null +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include "../src/refprop_wrapper.h" +#include "../src/refprop_library.h" +#include +#include + + +int main(int argc, char* argv[]){ + //char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + + + /* Define some new functions to access low-level refprop routines. + * + * The new functions should be used to compare the speed of the wrapper to the speed + * of the Fortran code and the Matlab implementation. + */ + +//# if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +//# define __ISWINDOWS__ +//# include +//# define _CRT_SECURE_NO_WARNINGS +//# elif __APPLE__ +//# define __ISAPPLE__ +//# elif __linux +//# define __ISLINUX__ +//# endif + + int nX=2; // Number of components + +# if defined(__ISWINDOWS__) + char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; +# elif defined(__ISLINUX__) + char thepathChar[255] = "/opt/refprop"; +# endif + + // Allocate space for objects + x = (double*) calloc(nX,sizeof(double)); + props = (double*) calloc(16+2*nX,sizeof(double)); + ders = (double*) calloc(21,sizeof(double)); + trns = (double*) calloc(3,sizeof(double)); + + char fluidname[255] = "ammoniaL|water"; + x[0] = 0.2; + x[1] = 1.0 - x[0]; + + double p = 50e5; + double h = 3e5; + double dh = 25e5; + int N = 50; + + double res = 0.0; + double h_in = 0.0; + + // Format the output properly + int decimals = 4; + int width = 10; + char buffer [50]; + //n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); + // printf ("[%s] is a string %d chars long\n",buffer,n); + + std::ostringstream out1,out2; + + // Then at the beginning: + time_t tstart, tend; + tstart = time(0); + + for (int count = 0; count < N; count++) { + h_in = h + dh * count / (N - 1); + res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG); + sprintf (buffer, "d = %8.4f [kg/m3]",props[4]); + out1 << buffer << std::endl; + sprintf (buffer, "T = %8.4f [K]",props[2]); + out1 << buffer << std::endl << std::endl; + } + + // And finally before the end: + tend = time(0); + out2 << "It took " << difftime(tend, tstart) << " second(s)." << std::endl; + + + //printf("%s", out1.str().c_str()); + + printf("%s", out2.str().c_str()); + + +// myString1 << "It took " << difftime(tend, tstart) << " second(s)." +// << std::endl; +// printf("%s", myString1.str().c_str()); + + + + + return 0; +} diff --git a/_wrapper/cpptest/refpropwrappertest_new.cpp b/_wrapper/cpptest/refpropwrappertest_new.cpp deleted file mode 100644 index f904c7b..0000000 --- a/_wrapper/cpptest/refpropwrappertest_new.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include "refprop_wrapper.h" -#include "refprop_library.h" -#include -#include - - - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -int main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255]; - double* x; - double *props; - double *ders; - double *trns; - double sumx; - int i; -// int nX = argc-5; - int DEBUG = 0; - - - -/* - int count; - printf ("This program was called with \"%s\".\n",argv[0]); - if (argc > 1) - { - for (count = 1; count < argc; count++) - { - printf("argv[%d] = %s\n", count, argv[count]); - } - } - else - { - printf("The command had no other arguments.\n"); - } -printf("argc is %li \n",argc); -*/ - - -/* - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); -// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); - return 1; - } -*/ -// usage -// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 - -int nX=2; - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - ders=(double*) calloc(21,sizeof(double)); - trns=(double*) calloc(3,sizeof(double)); - -x[0] = 0.5; -x[1] = 1.0-x[0]; -//x[2] = 1-x[1]; - - - - - -/* - sumx = 0; - for (i=0;i Date: Tue, 26 Nov 2013 08:26:46 +0100 Subject: [PATCH 37/57] Some testing.. --- Examples.mo | 7 + Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 163 ++++- Media/NH3_Water.mo | 5 + Media/Pentane.mo | 5 + Media/R410mix.mo | 5 + Media/Water.mo | 5 + Media/package.order | 2 +- Testers/PropsMixtureNH3H2O.mo | 12 +- Testers/PropsMixtureTwo.mo | 13 +- Testers/PropsPureSubstance.mo | 6 +- Testers/R410mixTester.mo | 2 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 ++++++++ Testers/package.order | 1 + _wrapper/bin/refprop_library.h | 788 +++++++++++++++++++++ _wrapper/src/refprop_wrapper.cpp | 32 +- _wrapper/src/refpropwrappertest.cpp | 275 +++++++ package.mo | 29 +- request | 1 + status | 1 + 19 files changed, 1584 insertions(+), 54 deletions(-) create mode 100644 Examples.mo create mode 100644 Media/NH3_Water.mo create mode 100644 Media/Pentane.mo create mode 100644 Media/R410mix.mo create mode 100644 Media/Water.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT.mo create mode 100644 _wrapper/bin/refprop_library.h create mode 100644 _wrapper/src/refpropwrappertest.cpp create mode 100644 request create mode 100644 status diff --git a/Examples.mo b/Examples.mo new file mode 100644 index 0000000..a40086b --- /dev/null +++ b/Examples.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" +extends Modelica.Icons.ExamplesPackage; +annotation(preferedView="info", + __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", + "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); +end Examples; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 2286fc7..4f849d9 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -69,7 +69,7 @@ partial package REFPROPMixtureTwoPhaseMedium input String errormsg; // input Integer debug=1; output Real val; - external"C" val= props_REFPROP( + external "C" val= props_REFPROP( what2calc, statevars, fluidnames, @@ -100,6 +100,7 @@ partial package REFPROPMixtureTwoPhaseMedium algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); // Modelica.Utilities.Streams.print("Calc "+what2calc); + val := getProp_REFPROP( what2calc, statevars, @@ -112,6 +113,7 @@ partial package REFPROPMixtureTwoPhaseMedium X, phase, errormsg) "just passing through"; + // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); @@ -529,6 +531,36 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_phX; + redeclare function extends setBubbleState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(bubbleEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 0, + sat.X, + phase) ",fluidnames)"; + end setBubbleState; + + redeclare function extends setDewState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(dewEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 1, + sat.X, + phase) ",fluidnames)"; + end setDewState; + function setState_pqX "Calculates medium properties from p,q,X" extends Modelica.Icons.Function; input Modelica.SIunits.AbsolutePressure p "Pressure"; @@ -654,14 +686,34 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hv := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hv := getProp_REFPROP_check( - "h", + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", "pq", + fluidnames, + ders, + trns, + props, sat.psat, 1, sat.X, - 1); + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hv :=props[10]; + end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" @@ -678,26 +730,66 @@ end ThermodynamicState; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; + //algorithm + // dv := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 1); + extends partialREFPROP; + algorithm - dv := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 1, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 1, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dv :=props[5]; + end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hl := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hl := getProp_REFPROP_check( - "h", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hl :=props[10]; + end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" @@ -714,14 +806,35 @@ end ThermodynamicState; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; + //algorithm + // dl := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 1); + + extends partialREFPROP; + algorithm - dl := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dl :=props[5]; + end bubbleDensity; redeclare replaceable function extends molarMass diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo new file mode 100644 index 0000000..4ca5e00 --- /dev/null +++ b/Media/NH3_Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package NH3_Water "Ammonia and water mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"ammoniaL","water"}); +end NH3_Water; diff --git a/Media/Pentane.mo b/Media/Pentane.mo new file mode 100644 index 0000000..22d21a6 --- /dev/null +++ b/Media/Pentane.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Pentane "Pentane from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"pentane"}); +end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo new file mode 100644 index 0000000..1d03112 --- /dev/null +++ b/Media/R410mix.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); +end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo new file mode 100644 index 0000000..67db3b5 --- /dev/null +++ b/Media/Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"water"}); +end Water; diff --git a/Media/package.order b/Media/package.order index 453f582..5841ec9 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,4 +1,4 @@ Pentane R410mix -R410 Water +NH3_Water diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 0292e7b..7a255ab 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; model PropsMixtureNH3H2O package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammonia","water"}, + final substanceNames={"ammoniaL","water"}, inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); Medium.ThermodynamicState state; @@ -13,6 +13,14 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; + Medium.SaturationProperties sat = Medium.setSat_pX(p,X); + + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + protected Modelica.SIunits.Temperature T_init = 400; Real[2] X_init = {0.5,0.5}; @@ -25,6 +33,8 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); + p = Medium.pressure(state); q = Medium.vapourQuality(state); + end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index 7b79646..a13a30c 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -8,8 +8,19 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Real q = Medium.vapourQuality(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); + + Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + + Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); + Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); + equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {0.5}; + props.Xi = {.5}; + end PropsMixtureTwo; diff --git a/Testers/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo index e23b4a8..94d9161 100644 --- a/Testers/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -5,7 +5,7 @@ model PropsPureSubstance //package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); //package Medium = REFPROPMedium(final substanceNames={"ammonia"}); //package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); +package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); Medium.BaseProperties props; @@ -15,14 +15,14 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final // Modelica.SIunits.SpecificEnthalpy h; // Modelica.SIunits.SpecificEntropy s; // Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); // Modelica.SIunits.MolarMass MM; Real q= Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; // Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); // Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); equation props.p = 1e5 "sine_p.y"; props.h = 0+time*722774; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo index c28c7c3..96f0283 100644 --- a/Testers/R410mixTester.mo +++ b/Testers/R410mixTester.mo @@ -1,6 +1,6 @@ within REFPROP2Modelica.Testers; model R410mixTester "Density of saturated R410 vapour" -package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); +package Medium = REFPROP2Modelica.Media.R410mix; Medium.BaseProperties props; Medium.Density d; Medium.SpecificEnthalpy h(start=300e3); diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo new file mode 100644 index 0000000..deb20fd --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -0,0 +1,286 @@ +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT + "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( + final mediumName="TwoPhaseMixtureWater", + final substanceNames={"water"}, + final reducedX = true, + final singleState=false, + reference_X=cat(1,fill(0,nX-1),{1}), + fluidConstants = BrineConstants); +// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + redeclare model extends BaseProperties "Base properties of medium" + Real GVF=q*d/d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case + equation + u = h - p/d; + MM = M_H2O; + R = Modelica.Constants.R/MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p,T,X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei gesättigter Lösung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s=0 "TODO"; + state = ThermodynamicState( + p=p, + T=T, + X=X, + X_l=X, + h=h, + GVF=GVF, + q=q, + s=0, + d_g=d_g, + d_l=d_l, + d=d, + phase=0) "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation (Documentation(info=""), + Documentation(revisions=" + +")); + end BaseProperties; + + redeclare function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); + algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); + end specificEnthalpy_pTX; + + redeclare function temperature_phX + "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); + algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); + end temperature_phX; + +redeclare record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" +/* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start=300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start=300) "density liquid phase"; + Density d_g(start=300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation (Documentation(info=" + +")); +end ThermodynamicState; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" + algorithm + hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); + end dewEnthalpy; + + redeclare function extends bubbleEnthalpy + "boiling curve specific enthalpy of water" + algorithm + hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); + end bubbleEnthalpy; + + redeclare function extends saturationTemperature + algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); + end saturationTemperature; + + redeclare function extends dynamicViscosity + algorithm + eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); + end dynamicViscosity; + +redeclare function extends specificEntropy "specific entropy of water" +algorithm + s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + +redeclare function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + +redeclare function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state := ThermodynamicState( + d=density_ps(p,s), + T=temperature_ps(p,s), + phase=0, + h=specificEnthalpy_ps(p,s), + p=p, + X=X, + s=s, + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_psX; + + redeclare function extends temperature "return temperature of ideal gas" + algorithm + T := state.T; + end temperature; + + redeclare function extends density "return density of ideal gas" + algorithm + d := state.d; + end density; + +redeclare function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state := ThermodynamicState( + d=density_pT(p,T), + T=T, + phase=0, + h=specificEnthalpy_pTX(p,s), + p=p, + X=X, + s=specificEntropy_pT(p.T), + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_pTX; + +redeclare function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + + redeclare function extends thermalConductivity + "Thermal conductivity of water" + algorithm + lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( + state.d, + state.T, + state.p, + state.phase); + end thermalConductivity; + + redeclare function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp := Modelica.Media.Water.IF97_Utilities.cp_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCp; + + redeclare function extends saturationPressure + algorithm + p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); + end saturationPressure; + + redeclare function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv := Modelica.Media.Water.IF97_Utilities.cv_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCv; + + annotation (Documentation(info=" +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index 1b48ebf..cbda809 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,4 +3,5 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester +Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h new file mode 100644 index 0000000..5231ae8 --- /dev/null +++ b/_wrapper/bin/refprop_library.h @@ -0,0 +1,788 @@ + +#ifndef REFPROP_LIB_H +#define REFPROP_LIB_H + +/* +// The idea here is to have a common header for Windows +// and gcc-like systems. The Windows branch should cover the +// functions provided by the .dll and the gcc part covers +// the compiled .so/.dym file. Name changes caused by gfortran +// are respected and should be accounted for. +*/ +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +// Do some manual changes to the function names +// if needed, uses CoolProp platform detection. +#if defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV __stdcall +// Do not redefine function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. Macros still need a value for the +// name function used below. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define RESIDUALdll RESIDUALdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll +#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # if defined( _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define RESIDUALdll residualdll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +#else // #elif defined(__ISLINUX__) +// Set some dummy names for the compiler +# define CALLCONV +# define RPVersion NOTAVAILABLE +# define SETPATHdll setpathdll +# define ABFL1dll abfl1dll +# define ABFL2dll abfl2dll +# define ACTVYdll actvydll +# define AGdll agdll +# define CCRITdll ccritdll +# define CP0dll cp0dll +# define CRITPdll critpdll +# define CSATKdll csatkdll +# define CV2PKdll cv2pkdll +# define CVCPKdll cvcpkdll +# define CVCPdll cvcpdll +# define DBDTdll dbdtdll +# define DBFL1dll dbfl1dll +# define DBFL2dll dbfl2dll +# define DDDPdll dddpdll +# define DDDTdll dddtdll +# define DEFLSHdll deflshdll +# define DHD1dll dhd1dll +# define DHFL1dll dhfl1dll +# define DHFL2dll dhfl2dll +# define DHFLSHdll dhflshdll +# define DIELECdll dielecdll +# define DOTFILLdll dotfilldll +# define DPDD2dll dpdd2dll +# define DPDDKdll dpddkdll +# define DPDDdll dpdddll +# define DPDTKdll dpdtkdll +# define DPDTdll dpdtdll +# define DPTSATKdll dptsatkdll +# define DSFLSHdll dsflshdll +# define DSFL1dll dsfl1dll +# define DSFL2dll dsfl2dll +# define ENTHALdll enthaldll +# define ENTROdll entrodll +# define ESFLSHdll esflshdll +# define FGCTYdll fgctydll +# define FPVdll fpvdll +# define GERG04dll gerg04dll +# define GETFIJdll getfijdll +# define GETKTVdll getktvdll +# define GIBBSdll gibbsdll +# define HSFLSHdll hsflshdll +# define INFOdll infodll +# define LIMITKdll limitkdll +# define LIMITSdll limitsdll +# define LIMITXdll limitxdll +# define MELTPdll meltpdll +# define MELTTdll melttdll +# define MLTH2Odll mlth2odll +# define NAMEdll namedll +# define PDFL1dll pdfl1dll +# define PDFLSHdll pdflshdll +# define PEFLSHdll peflshdll +# define PHFL1dll phfl1dll +# define PHFLSHdll phflshdll +# define PQFLSHdll pqflshdll +# define PREOSdll preosdll +# define PRESSdll pressdll +# define PSFL1dll psfl1dll +# define PSFLSHdll psflshdll +# define PUREFLDdll pureflddll +# define QMASSdll qmassdll +# define QMOLEdll qmoledll +# define RESIDUALdll residualdll +# define SATDdll satddll +# define SATEdll satedll +# define SATHdll sathdll +# define SATPdll satpdll +# define SATSdll satsdll +# define SATTdll sattdll +# define SETAGAdll setagadll +# define SETKTVdll setktvdll +# define SETMIXdll setmixdll +# define SETMODdll setmoddll +# define SETREFdll setrefdll +# define SETUPdll setupdll +//# define SPECGRdll specgrdll // not found in library +# define SUBLPdll sublpdll +# define SUBLTdll subltdll +# define SURFTdll surftdll +# define SURTENdll surtendll +# define TDFLSHdll tdflshdll +# define TEFLSHdll teflshdll +# define THERM0dll therm0dll +# define THERM2dll therm2dll +# define THERM3dll therm3dll +# define THERMdll thermdll +# define THFLSHdll thflshdll +# define TPFLSHdll tpflshdll +# define TPFL2dll tpfl2dll +# define TPRHOdll tprhodll +# define TQFLSHdll tqflshdll +# define TRNPRPdll trnprpdll +# define TSFLSHdll tsflshdll +# define VIRBdll virbdll +# define VIRCdll vircdll +# define WMOLdll wmoldll +# define XMASSdll xmassdll +# define XMOLEdll xmoledll +#endif // else branch +// +// +// Only continue if function names have been defined. +// We might want to include some more tests here... +#if defined(RPVersion) +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#if defined(__cplusplus) +extern "C" { +#endif + typedef void (CALLCONV RPVersion_TYPE)( char* ); + typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + // + typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); + typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); + typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); + typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); + typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); + typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); + typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); + typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); + typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); + typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PREOSdll_TYPE)(long &); + typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PUREFLDdll_TYPE)(long &); + typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); + typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); + typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); + typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); + typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); + typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); + typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); +// +// Disabled because we prefer pointers here! +// // Declare the functions for direct access, +// RPVersion_TYPE RPVersion; +// SETPATHdll_TYPE SETPATHdll; +// ABFL1dll_TYPE ABFL1dll; +// ABFL2dll_TYPE ABFL2dll; +// ACTVYdll_TYPE ACTVYdll; +// AGdll_TYPE AGdll; +// CCRITdll_TYPE CCRITdll; +// CP0dll_TYPE CP0dll; +// CRITPdll_TYPE CRITPdll; +// CSATKdll_TYPE CSATKdll; +// CV2PKdll_TYPE CV2PKdll; +// CVCPKdll_TYPE CVCPKdll; +// CVCPdll_TYPE CVCPdll; +// DBDTdll_TYPE DBDTdll; +// DBFL1dll_TYPE DBFL1dll; +// DBFL2dll_TYPE DBFL2dll; +// DDDPdll_TYPE DDDPdll; +// DDDTdll_TYPE DDDTdll; +// DEFLSHdll_TYPE DEFLSHdll; +// DHD1dll_TYPE DHD1dll; +// DHFLSHdll_TYPE DHFLSHdll; +// DHFL1dll_TYPE DHFL1dll; +// DHFL2dll_TYPE DHFL2dll; +// DIELECdll_TYPE DIELECdll; +// DOTFILLdll_TYPE DOTFILLdll; +// DPDD2dll_TYPE DPDD2dll; +// DPDDKdll_TYPE DPDDKdll; +// DPDDdll_TYPE DPDDdll; +// DPDTKdll_TYPE DPDTKdll; +// DPDTdll_TYPE DPDTdll; +// DPTSATKdll_TYPE DPTSATKdll; +// DSFLSHdll_TYPE DSFLSHdll; +// DSFL1dll_TYPE DSFL1dll; +// DSFL2dll_TYPE DSFL2dll; +// ENTHALdll_TYPE ENTHALdll; +// ENTROdll_TYPE ENTROdll; +// ESFLSHdll_TYPE ESFLSHdll; +// FGCTYdll_TYPE FGCTYdll; +// FPVdll_TYPE FPVdll; +// GERG04dll_TYPE GERG04dll; +// GETFIJdll_TYPE GETFIJdll; +// GETKTVdll_TYPE GETKTVdll; +// GIBBSdll_TYPE GIBBSdll; +// HSFLSHdll_TYPE HSFLSHdll; +// INFOdll_TYPE INFOdll; +// LIMITKdll_TYPE LIMITKdll; +// LIMITSdll_TYPE LIMITSdll; +// LIMITXdll_TYPE LIMITXdll; +// MELTPdll_TYPE MELTPdll; +// MELTTdll_TYPE MELTTdll; +// MLTH2Odll_TYPE MLTH2Odll; +// NAMEdll_TYPE NAMEdll; +// PDFL1dll_TYPE PDFL1dll; +// PDFLSHdll_TYPE PDFLSHdll; +// PEFLSHdll_TYPE PEFLSHdll; +// PHFL1dll_TYPE PHFL1dll; +// PHFLSHdll_TYPE PHFLSHdll; +// PQFLSHdll_TYPE PQFLSHdll; +// PREOSdll_TYPE PREOSdll; +// PRESSdll_TYPE PRESSdll; +// PSFL1dll_TYPE PSFL1dll; +// PSFLSHdll_TYPE PSFLSHdll; +// PUREFLDdll_TYPE PUREFLDdll; +// QMASSdll_TYPE QMASSdll; +// QMOLEdll_TYPE QMOLEdll; +// SATDdll_TYPE SATDdll; +// SATEdll_TYPE SATEdll; +// SATHdll_TYPE SATHdll; +// SATPdll_TYPE SATPdll; +// SATSdll_TYPE SATSdll; +// SATTdll_TYPE SATTdll; +// SETAGAdll_TYPE SETAGAdll; +// SETKTVdll_TYPE SETKTVdll; +// SETMIXdll_TYPE SETMIXdll; +// SETMODdll_TYPE SETMODdll; +// SETREFdll_TYPE SETREFdll; +// SETUPdll_TYPE SETUPdll; +//// SPECGRdll_TYPE SPECGRdll; // not found in library +// SUBLPdll_TYPE SUBLPdll; +// SUBLTdll_TYPE SUBLTdll; +// SURFTdll_TYPE SURFTdll; +// SURTENdll_TYPE SURTENdll; +// TDFLSHdll_TYPE TDFLSHdll; +// TEFLSHdll_TYPE TEFLSHdll; +// THERM0dll_TYPE THERM0dll; +// THERM2dll_TYPE THERM2dll; +// THERM3dll_TYPE THERM3dll; +// THERMdll_TYPE THERMdll; +// THFLSHdll_TYPE THFLSHdll; +// TPFLSHdll_TYPE TPFLSHdll; +// TPFL2dll_TYPE TPFL2dll; +// TPRHOdll_TYPE TPRHOdll; +// TQFLSHdll_TYPE TQFLSHdll; +// TRNPRPdll_TYPE TRNPRPdll; +// TSFLSHdll_TYPE TSFLSHdll; +// VIRBdll_TYPE VIRBdll; +// VIRCdll_TYPE VIRCdll; +// WMOLdll_TYPE WMOLdll; +// XMASSdll_TYPE XMASSdll; +// XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus +#endif // defined(RPversion) +#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index ebcecad..1b6c65e 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -612,6 +612,7 @@ double loadLibrary() { if (RefpropdllInstance == NULL) { // Refprop is not loaded #if defined(__ISWINDOWS__) #if defined(UNICODE) + //RefpropdllInstance = LoadLibrary((LPCWSTR)libName); RefpropdllInstance = LoadLibraryW((LPCWSTR)libName); #else RefpropdllInstance = LoadLibrary((LPCSTR)libName); @@ -803,12 +804,6 @@ double initRefprop() { printf("check types and names in header file.\n"); return FAIL; } - // Set the desired equation of state, consult the Refprop - // documentation for more details. - // 0 : use default values - // 2 : force Peng-Robinson - long eosSwitch = 0; - PREOSdll(eosSwitch); return OK; } else { if (debug) printf ("Library loaded, not doing anything.\n"); @@ -843,6 +838,9 @@ double setFluids(std::string sPath, std::string sFluids, char* error){ if (loadedFluids.compare(sFluids)) { // The fluid is not already loaded std::vector components_split = strsplit(sFluids,'|');// Split into components + + //printf ("%s \n",RefString.c_str()); + RefString.clear(); // Flush out fluid string // Build new fluid string @@ -983,7 +981,7 @@ double getS_modelica() { double getWM_modelica(){ //molecular weight - return dwm/1000; + return dwm/1000; // g/mol to kg/mol } double getDL_modelica(){ @@ -1369,6 +1367,12 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = -1. * ddhdp_d / ddhdd_p; ddddh_p = 1./ddhdd_p; } else { // two-phase region, get derivative of density with respect to enthalpy numerically + + + // TODO + ddddp_h = -1; + ddddh_p = -1; + /* if (debug) printf ("Using two-phase derivatives.\n"); deltaP = 0.00005; // 0.05 Pascal difference pLow = dp - 0.5*deltaP; @@ -1396,6 +1400,7 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + */ } } else { // We have a problem! @@ -1674,7 +1679,7 @@ OUTPUT // Set variables to input values if ( strCompare(in1, in2) ) { sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return -1; + return FAIL; } memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; @@ -1907,12 +1912,15 @@ OUTPUT updateProps(props, lerr); - //int outVal = ders_REFPROP(ders,errormsg,debug); - //if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - //outVal = trns_REFPROP(trns,errormsg,debug); - //if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + // TODO + /* + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + */ if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/src/refpropwrappertest.cpp new file mode 100644 index 0000000..483f5f2 --- /dev/null +++ b/_wrapper/src/refpropwrappertest.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;iContact for original implementation:

-

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

-


Contact for this version:

-

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

-", - revisions = " + + annotation (version="0.2", uses(Modelica(version="3.2")), + Documentation(info=" +

+Documentation is found in the packages. Installation directions are found in both REFPROP packages. +

+

Contact for original implementation:

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +", + revisions=" ")); end REFPROP2Modelica; diff --git a/request b/request new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/request @@ -0,0 +1 @@ + diff --git a/status b/status new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/status @@ -0,0 +1 @@ + From b4a03bbc05985a368cd8faf841b0663a7de463c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 26 Nov 2013 08:46:56 +0100 Subject: [PATCH 38/57] Revert "Some testing.." This reverts commit 368df8a142cc335d59294aee095138904a564f3f. --- Examples.mo | 7 - Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 163 +---- Media/NH3_Water.mo | 5 - Media/Pentane.mo | 5 - Media/R410mix.mo | 5 - Media/Water.mo | 5 - Media/package.order | 2 +- Testers/PropsMixtureNH3H2O.mo | 12 +- Testers/PropsMixtureTwo.mo | 13 +- Testers/PropsPureSubstance.mo | 6 +- Testers/R410mixTester.mo | 2 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 -------- Testers/package.order | 1 - _wrapper/bin/refprop_library.h | 788 --------------------- _wrapper/src/refprop_wrapper.cpp | 32 +- _wrapper/src/refpropwrappertest.cpp | 275 ------- package.mo | 29 +- request | 1 - status | 1 - 19 files changed, 54 insertions(+), 1584 deletions(-) delete mode 100644 Examples.mo delete mode 100644 Media/NH3_Water.mo delete mode 100644 Media/Pentane.mo delete mode 100644 Media/R410mix.mo delete mode 100644 Media/Water.mo delete mode 100644 Testers/Water_MixtureTwoPhase_pT.mo delete mode 100644 _wrapper/bin/refprop_library.h delete mode 100644 _wrapper/src/refpropwrappertest.cpp delete mode 100644 request delete mode 100644 status diff --git a/Examples.mo b/Examples.mo deleted file mode 100644 index a40086b..0000000 --- a/Examples.mo +++ /dev/null @@ -1,7 +0,0 @@ -within REFPROP2Modelica; -package Examples "Demonstration of the usage of the library" -extends Modelica.Icons.ExamplesPackage; -annotation(preferedView="info", - __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", - "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); -end Examples; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 4f849d9..2286fc7 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -69,7 +69,7 @@ partial package REFPROPMixtureTwoPhaseMedium input String errormsg; // input Integer debug=1; output Real val; - external "C" val= props_REFPROP( + external"C" val= props_REFPROP( what2calc, statevars, fluidnames, @@ -100,7 +100,6 @@ partial package REFPROPMixtureTwoPhaseMedium algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); // Modelica.Utilities.Streams.print("Calc "+what2calc); - val := getProp_REFPROP( what2calc, statevars, @@ -113,7 +112,6 @@ partial package REFPROPMixtureTwoPhaseMedium X, phase, errormsg) "just passing through"; - // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); @@ -531,36 +529,6 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_phX; - redeclare function extends setBubbleState - "set the thermodynamic state on the bubble line" - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(bubbleEnthalpy(sat)) + ",X)..."); - end if; - state := setState( - "pq", - sat.psat, - 0, - sat.X, - phase) ",fluidnames)"; - end setBubbleState; - - redeclare function extends setDewState - "set the thermodynamic state on the bubble line" - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(dewEnthalpy(sat)) + ",X)..."); - end if; - state := setState( - "pq", - sat.psat, - 1, - sat.X, - phase) ",fluidnames)"; - end setDewState; - function setState_pqX "Calculates medium properties from p,q,X" extends Modelica.Icons.Function; input Modelica.SIunits.AbsolutePressure p "Pressure"; @@ -686,34 +654,14 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hv := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", + hv := getProp_REFPROP_check( + "h", "pq", - fluidnames, - ders, - trns, - props, sat.psat, 1, sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hv :=props[10]; - + 1); end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" @@ -730,66 +678,26 @@ end ThermodynamicState; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; - //algorithm - // dv := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 1); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 1, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dv :=props[5]; - + dv := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 1, + sat.X, + 1); end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hl := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hl :=props[10]; - + hl := getProp_REFPROP_check( + "h", + "pq", + sat.psat, + 0, + sat.X, + 1); end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" @@ -806,35 +714,14 @@ end ThermodynamicState; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; - //algorithm - // dl := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 1); - - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dl :=props[5]; - + dl := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 0, + sat.X, + 1); end bubbleDensity; redeclare replaceable function extends molarMass diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo deleted file mode 100644 index 4ca5e00..0000000 --- a/Media/NH3_Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package NH3_Water "Ammonia and water mixture by REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"ammoniaL","water"}); -end NH3_Water; diff --git a/Media/Pentane.mo b/Media/Pentane.mo deleted file mode 100644 index 22d21a6..0000000 --- a/Media/Pentane.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Pentane "Pentane from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"pentane"}); -end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo deleted file mode 100644 index 1d03112..0000000 --- a/Media/R410mix.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package R410mix "R410 defined as mixture in REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); -end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo deleted file mode 100644 index 67db3b5..0000000 --- a/Media/Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Water "Water from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"water"}); -end Water; diff --git a/Media/package.order b/Media/package.order index 5841ec9..453f582 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,4 +1,4 @@ Pentane R410mix +R410 Water -NH3_Water diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 7a255ab..0292e7b 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; model PropsMixtureNH3H2O package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammoniaL","water"}, + final substanceNames={"ammonia","water"}, inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); Medium.ThermodynamicState state; @@ -13,14 +13,6 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; - Medium.SaturationProperties sat = Medium.setSat_pX(p,X); - - Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); - Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); - - Medium.Density dl = Medium.bubbleDensity(sat); - Medium.Density dv = Medium.dewDensity(sat); - protected Modelica.SIunits.Temperature T_init = 400; Real[2] X_init = {0.5,0.5}; @@ -33,8 +25,6 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); - p = Medium.pressure(state); q = Medium.vapourQuality(state); - end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index a13a30c..7b79646 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -8,19 +8,8 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Real q = Medium.vapourQuality(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); - - Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); - Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); - Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); - Medium.Density dl = Medium.bubbleDensity(sat); - Medium.Density dv = Medium.dewDensity(sat); - - Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); - Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); - equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {.5}; - + props.Xi = {0.5}; end PropsMixtureTwo; diff --git a/Testers/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo index 94d9161..e23b4a8 100644 --- a/Testers/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -5,7 +5,7 @@ model PropsPureSubstance //package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); //package Medium = REFPROPMedium(final substanceNames={"ammonia"}); //package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); Medium.BaseProperties props; @@ -15,14 +15,14 @@ package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNam // Modelica.SIunits.SpecificEnthalpy h; // Modelica.SIunits.SpecificEntropy s; // Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); // Modelica.SIunits.MolarMass MM; Real q= Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; // Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); // Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); equation props.p = 1e5 "sine_p.y"; props.h = 0+time*722774; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo index 96f0283..c28c7c3 100644 --- a/Testers/R410mixTester.mo +++ b/Testers/R410mixTester.mo @@ -1,6 +1,6 @@ within REFPROP2Modelica.Testers; model R410mixTester "Density of saturated R410 vapour" -package Medium = REFPROP2Modelica.Media.R410mix; +package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); Medium.BaseProperties props; Medium.Density d; Medium.SpecificEnthalpy h(start=300e3); diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo deleted file mode 100644 index deb20fd..0000000 --- a/Testers/Water_MixtureTwoPhase_pT.mo +++ /dev/null @@ -1,286 +0,0 @@ -within REFPROP2Modelica.Testers; -package Water_MixtureTwoPhase_pT - "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( - final mediumName="TwoPhaseMixtureWater", - final substanceNames={"water"}, - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = BrineConstants); -// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - redeclare model extends BaseProperties "Base properties of medium" - Real GVF=q*d/d_g "gas void fraction"; - Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ - Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); - Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); - Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) - "(min=0,max=1) gas phase mass fraction"; - // Integer phase_out "calculated phase"; - //END no gas case - equation - u = h - p/d; - MM = M_H2O; - R = Modelica.Constants.R/MM; - //End GVF - //DENSITY - // q = vapourQuality(state); - d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); - // d = d_l/(1-q*(1-d_l/d_g)); - //End DENSITY - //ENTHALPY - h = specificEnthalpy_pTX(p,T,X); - /* - if (p_H2O>p) then - h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); - else - h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); - end if; - h_gas_dissolved = 0; - Delta_h_solution = solutionEnthalpy(T) - "TODO: gilt nur bei gesättigter Lösung"; -*/ - //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); - //End ENTHALPY - s=0 "TODO"; - state = ThermodynamicState( - p=p, - T=T, - X=X, - X_l=X, - h=h, - GVF=GVF, - q=q, - s=0, - d_g=d_g, - d_l=d_l, - d=d, - phase=0) "phase_out"; - sat.psat = p "TODO"; - sat.Tsat = T "saturationTemperature(p) TODO"; - sat.X = X; - annotation (Documentation(info=""), - Documentation(revisions=" - -")); - end BaseProperties; - - redeclare function specificEnthalpy_pTX - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - /* input MassFraction q "(min=0,max=1)"; - input Real y "molar fraction of gas in gas phase";*/ - // input Real[3] TP; - output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); - algorithm - // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); - annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); - end specificEnthalpy_pTX; - - redeclare function temperature_phX - "numerically inverts specificEnthalpy_liquid_pTX" - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); - algorithm - // Modelica.Utilities.Streams.print("temperature_phX"); - annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); - end temperature_phX; - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T(unit="K") "Temperature of medium"; - MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Density d(start=300) "density"; - Real GVF "Gas Void Fraction"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real q "vapor quality on a mass basis [mass vapor/total mass]"; - annotation (Documentation(info=" - -")); -end ThermodynamicState; - - redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" - algorithm - hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); - end dewEnthalpy; - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - algorithm - hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); - end bubbleEnthalpy; - - redeclare function extends saturationTemperature - algorithm - //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); - T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); - end saturationTemperature; - - redeclare function extends dynamicViscosity - algorithm - eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); - end dynamicViscosity; - -redeclare function extends specificEntropy "specific entropy of water" -algorithm - s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); -end specificEntropy; - -redeclare function specificEnthalpy_ps - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEnthalpy_ps; - -redeclare function extends setState_psX - "Return thermodynamic state of water as function of p and s" -algorithm - state := ThermodynamicState( - d=density_ps(p,s), - T=temperature_ps(p,s), - phase=0, - h=specificEnthalpy_ps(p,s), - p=p, - X=X, - s=s, - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_psX; - - redeclare function extends temperature "return temperature of ideal gas" - algorithm - T := state.T; - end temperature; - - redeclare function extends density "return density of ideal gas" - algorithm - d := state.d; - end density; - -redeclare function extends setState_pTX - "Return thermodynamic state of water as function of p and T" -algorithm - state := ThermodynamicState( - d=density_pT(p,T), - T=T, - phase=0, - h=specificEnthalpy_pTX(p,s), - p=p, - X=X, - s=specificEntropy_pT(p.T), - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_pTX; - -redeclare function specificEntropy_pTX - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy T "Specific entropy"; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy s "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEntropy_pTX; - - redeclare function extends thermalConductivity - "Thermal conductivity of water" - algorithm - lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( - state.d, - state.T, - state.p, - state.phase); - end thermalConductivity; - - redeclare function extends specificHeatCapacityCp - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); - else - cp := Modelica.Media.Water.IF97_Utilities.cp_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCp; - - redeclare function extends saturationPressure - algorithm - p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); - end saturationPressure; - - redeclare function extends specificHeatCapacityCv - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); - else - cv := Modelica.Media.Water.IF97_Utilities.cv_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCv; - - annotation (Documentation(info=" -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index cbda809..1b48ebf 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,5 +3,4 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester -Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h deleted file mode 100644 index 5231ae8..0000000 --- a/_wrapper/bin/refprop_library.h +++ /dev/null @@ -1,788 +0,0 @@ - -#ifndef REFPROP_LIB_H -#define REFPROP_LIB_H - -/* -// The idea here is to have a common header for Windows -// and gcc-like systems. The Windows branch should cover the -// functions provided by the .dll and the gcc part covers -// the compiled .so/.dym file. Name changes caused by gfortran -// are respected and should be accounted for. -*/ -#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) -# define __ISWINDOWS__ -# include -# define _CRT_SECURE_NO_WARNINGS -#elif __APPLE__ -# define __ISAPPLE__ -#elif __linux -# define __ISLINUX__ -#endif - -// Do some manual changes to the function names -// if needed, uses CoolProp platform detection. -#if defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV __stdcall -// Do not redefine function names for the shared library, -// in this case it is the REFPROP.dll and no special -// names are needed. Macros still need a value for the -// name function used below. -# define RPVersion RPVersion -# define SETPATHdll SETPATHdll -# define ABFL1dll ABFL1dll -# define ABFL2dll ABFL2dll -# define ACTVYdll ACTVYdll -# define AGdll AGdll -# define CCRITdll CCRITdll -# define CP0dll CP0dll -# define CRITPdll CRITPdll -# define CSATKdll CSATKdll -# define CV2PKdll CV2PKdll -# define CVCPKdll CVCPKdll -# define CVCPdll CVCPdll -# define DBDTdll DBDTdll -# define DBFL1dll DBFL1dll -# define DBFL2dll DBFL2dll -# define DDDPdll DDDPdll -# define DDDTdll DDDTdll -# define DEFLSHdll DEFLSHdll -# define DHD1dll DHD1dll -# define DHFL1dll DHFL1dll -# define DHFL2dll DHFL2dll -# define DHFLSHdll DHFLSHdll -# define DIELECdll DIELECdll -# define DOTFILLdll DOTFILLdll -# define DPDD2dll DPDD2dll -# define DPDDKdll DPDDKdll -# define DPDDdll DPDDdll -# define DPDTKdll DPDTKdll -# define DPDTdll DPDTdll -# define DPTSATKdll DPTSATKdll -# define DSFLSHdll DSFLSHdll -# define DSFL1dll DSFL1dll -# define DSFL2dll DSFL2dll -# define ENTHALdll ENTHALdll -# define ENTROdll ENTROdll -# define ESFLSHdll ESFLSHdll -# define FGCTYdll FGCTYdll -# define FPVdll FPVdll -# define GERG04dll GERG04dll -# define GETFIJdll GETFIJdll -# define GETKTVdll GETKTVdll -# define GIBBSdll GIBBSdll -# define HSFLSHdll HSFLSHdll -# define INFOdll INFOdll -# define LIMITKdll LIMITKdll -# define LIMITSdll LIMITSdll -# define LIMITXdll LIMITXdll -# define MELTPdll MELTPdll -# define MELTTdll MELTTdll -# define MLTH2Odll MLTH2Odll -# define NAMEdll NAMEdll -# define PDFL1dll PDFL1dll -# define PDFLSHdll PDFLSHdll -# define PEFLSHdll PEFLSHdll -# define PHFL1dll PHFL1dll -# define PHFLSHdll PHFLSHdll -# define PQFLSHdll PQFLSHdll -# define PREOSdll PREOSdll -# define PRESSdll PRESSdll -# define PSFL1dll PSFL1dll -# define PSFLSHdll PSFLSHdll -# define PUREFLDdll PUREFLDdll -# define QMASSdll QMASSdll -# define QMOLEdll QMOLEdll -# define RESIDUALdll RESIDUALdll -# define SATDdll SATDdll -# define SATEdll SATEdll -# define SATHdll SATHdll -# define SATPdll SATPdll -# define SATSdll SATSdll -# define SATTdll SATTdll -# define SETAGAdll SETAGAdll -# define SETKTVdll SETKTVdll -# define SETMIXdll SETMIXdll -# define SETMODdll SETMODdll -# define SETREFdll SETREFdll -# define SETUPdll SETUPdll -//# define SPECGRdll SPECGRdll // not found in library -# define SUBLPdll SUBLPdll -# define SUBLTdll SUBLTdll -# define SURFTdll SURFTdll -# define SURTENdll SURTENdll -# define TDFLSHdll TDFLSHdll -# define TEFLSHdll TEFLSHdll -# define THERM0dll THERM0dll -# define THERM2dll THERM2dll -# define THERM3dll THERM3dll -# define THERMdll THERMdll -# define THFLSHdll THFLSHdll -# define TPFLSHdll TPFLSHdll -# define TPFL2dll TPFL2dll -# define TPRHOdll TPRHOdll -# define TQFLSHdll TQFLSHdll -# define TRNPRPdll TRNPRPdll -# define TSFLSHdll TSFLSHdll -# define VIRBdll VIRBdll -# define VIRCdll VIRCdll -# define WMOLdll WMOLdll -# define XMASSdll XMASSdll -# define XMOLEdll XMOLEdll -#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV -// Define function names for the shared library, -// in this case it is the librefprop.so and the -// names might change on some systems during -// the compilation of the Fortran files. -// Possible other branches for this code could be: -// # if !defined(_AIX) -// # if !defined(__hpux) -// # if defined( _CRAY -// However, I cannot test that and therefore do not include it. -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define RESIDUALdll residualdll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -//# define SPECGRdll specgrdll_ // not found in library -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -#else // #elif defined(__ISLINUX__) -// Set some dummy names for the compiler -# define CALLCONV -# define RPVersion NOTAVAILABLE -# define SETPATHdll setpathdll -# define ABFL1dll abfl1dll -# define ABFL2dll abfl2dll -# define ACTVYdll actvydll -# define AGdll agdll -# define CCRITdll ccritdll -# define CP0dll cp0dll -# define CRITPdll critpdll -# define CSATKdll csatkdll -# define CV2PKdll cv2pkdll -# define CVCPKdll cvcpkdll -# define CVCPdll cvcpdll -# define DBDTdll dbdtdll -# define DBFL1dll dbfl1dll -# define DBFL2dll dbfl2dll -# define DDDPdll dddpdll -# define DDDTdll dddtdll -# define DEFLSHdll deflshdll -# define DHD1dll dhd1dll -# define DHFL1dll dhfl1dll -# define DHFL2dll dhfl2dll -# define DHFLSHdll dhflshdll -# define DIELECdll dielecdll -# define DOTFILLdll dotfilldll -# define DPDD2dll dpdd2dll -# define DPDDKdll dpddkdll -# define DPDDdll dpdddll -# define DPDTKdll dpdtkdll -# define DPDTdll dpdtdll -# define DPTSATKdll dptsatkdll -# define DSFLSHdll dsflshdll -# define DSFL1dll dsfl1dll -# define DSFL2dll dsfl2dll -# define ENTHALdll enthaldll -# define ENTROdll entrodll -# define ESFLSHdll esflshdll -# define FGCTYdll fgctydll -# define FPVdll fpvdll -# define GERG04dll gerg04dll -# define GETFIJdll getfijdll -# define GETKTVdll getktvdll -# define GIBBSdll gibbsdll -# define HSFLSHdll hsflshdll -# define INFOdll infodll -# define LIMITKdll limitkdll -# define LIMITSdll limitsdll -# define LIMITXdll limitxdll -# define MELTPdll meltpdll -# define MELTTdll melttdll -# define MLTH2Odll mlth2odll -# define NAMEdll namedll -# define PDFL1dll pdfl1dll -# define PDFLSHdll pdflshdll -# define PEFLSHdll peflshdll -# define PHFL1dll phfl1dll -# define PHFLSHdll phflshdll -# define PQFLSHdll pqflshdll -# define PREOSdll preosdll -# define PRESSdll pressdll -# define PSFL1dll psfl1dll -# define PSFLSHdll psflshdll -# define PUREFLDdll pureflddll -# define QMASSdll qmassdll -# define QMOLEdll qmoledll -# define RESIDUALdll residualdll -# define SATDdll satddll -# define SATEdll satedll -# define SATHdll sathdll -# define SATPdll satpdll -# define SATSdll satsdll -# define SATTdll sattdll -# define SETAGAdll setagadll -# define SETKTVdll setktvdll -# define SETMIXdll setmixdll -# define SETMODdll setmoddll -# define SETREFdll setrefdll -# define SETUPdll setupdll -//# define SPECGRdll specgrdll // not found in library -# define SUBLPdll sublpdll -# define SUBLTdll subltdll -# define SURFTdll surftdll -# define SURTENdll surtendll -# define TDFLSHdll tdflshdll -# define TEFLSHdll teflshdll -# define THERM0dll therm0dll -# define THERM2dll therm2dll -# define THERM3dll therm3dll -# define THERMdll thermdll -# define THFLSHdll thflshdll -# define TPFLSHdll tpflshdll -# define TPFL2dll tpfl2dll -# define TPRHOdll tprhodll -# define TQFLSHdll tqflshdll -# define TRNPRPdll trnprpdll -# define TSFLSHdll tsflshdll -# define VIRBdll virbdll -# define VIRCdll vircdll -# define WMOLdll wmoldll -# define XMASSdll xmassdll -# define XMOLEdll xmoledll -#endif // else branch -// -// -// Only continue if function names have been defined. -// We might want to include some more tests here... -#if defined(RPVersion) -// define new macros for function names -// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value -#include -#include -#define STR_VALUE(arg) #arg -#define FUNCTION_NAME(name) STR_VALUE(name) -// -// Prepare the strings to be used by the functions that -// handle the library later on. -#define RPVersion_NAME FUNCTION_NAME(RPVersion) -#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) -#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) -#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) -#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) -#define AGdll_NAME FUNCTION_NAME(AGdll) -#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) -#define CP0dll_NAME FUNCTION_NAME(CP0dll) -#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) -#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) -#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) -#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) -#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) -#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) -#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) -#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) -#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) -#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) -#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) -#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) -#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) -#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) -#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) -#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) -#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) -#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) -#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) -#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) -#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) -#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) -#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) -#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) -#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) -#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) -#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) -#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) -#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) -#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) -#define FPVdll_NAME FUNCTION_NAME(FPVdll) -#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) -#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) -#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) -#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) -#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) -#define INFOdll_NAME FUNCTION_NAME(INFOdll) -#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) -#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) -#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) -#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) -#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) -#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) -#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) -#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) -#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) -#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) -#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) -#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) -#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) -#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) -#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) -#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) -#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) -#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) -#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) -#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) -#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) -#define SATDdll_NAME FUNCTION_NAME(SATDdll) -#define SATEdll_NAME FUNCTION_NAME(SATEdll) -#define SATHdll_NAME FUNCTION_NAME(SATHdll) -#define SATPdll_NAME FUNCTION_NAME(SATPdll) -#define SATSdll_NAME FUNCTION_NAME(SATSdll) -#define SATTdll_NAME FUNCTION_NAME(SATTdll) -#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) -#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) -#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) -#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) -#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) -#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) -//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library -#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) -#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) -#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) -#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) -#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) -#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) -#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) -#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) -#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) -#define THERMdll_NAME FUNCTION_NAME(THERMdll) -#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) -#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) -#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) -#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) -#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) -#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) -#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) -#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) -#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) -#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) -#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) -#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) -// -// I'll try to follow this example from: -// http://www.gershnik.com/tips/cpp.asp -// function type: typedef void [compiler stuff] func_t(int, float); -// function declaration: func_t func; -// pointer type: typedef func_t * func_ptr; -#if defined(__cplusplus) -extern "C" { -#endif - typedef void (CALLCONV RPVersion_TYPE)( char* ); - typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); - // - typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); - typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); - typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); - typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); - typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); - typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); - typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); - typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); - typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); - typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PREOSdll_TYPE)(long &); - typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PUREFLDdll_TYPE)(long &); - typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); - typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); - typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); - typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); - typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); - typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); - typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); - typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); -// -// Disabled because we prefer pointers here! -// // Declare the functions for direct access, -// RPVersion_TYPE RPVersion; -// SETPATHdll_TYPE SETPATHdll; -// ABFL1dll_TYPE ABFL1dll; -// ABFL2dll_TYPE ABFL2dll; -// ACTVYdll_TYPE ACTVYdll; -// AGdll_TYPE AGdll; -// CCRITdll_TYPE CCRITdll; -// CP0dll_TYPE CP0dll; -// CRITPdll_TYPE CRITPdll; -// CSATKdll_TYPE CSATKdll; -// CV2PKdll_TYPE CV2PKdll; -// CVCPKdll_TYPE CVCPKdll; -// CVCPdll_TYPE CVCPdll; -// DBDTdll_TYPE DBDTdll; -// DBFL1dll_TYPE DBFL1dll; -// DBFL2dll_TYPE DBFL2dll; -// DDDPdll_TYPE DDDPdll; -// DDDTdll_TYPE DDDTdll; -// DEFLSHdll_TYPE DEFLSHdll; -// DHD1dll_TYPE DHD1dll; -// DHFLSHdll_TYPE DHFLSHdll; -// DHFL1dll_TYPE DHFL1dll; -// DHFL2dll_TYPE DHFL2dll; -// DIELECdll_TYPE DIELECdll; -// DOTFILLdll_TYPE DOTFILLdll; -// DPDD2dll_TYPE DPDD2dll; -// DPDDKdll_TYPE DPDDKdll; -// DPDDdll_TYPE DPDDdll; -// DPDTKdll_TYPE DPDTKdll; -// DPDTdll_TYPE DPDTdll; -// DPTSATKdll_TYPE DPTSATKdll; -// DSFLSHdll_TYPE DSFLSHdll; -// DSFL1dll_TYPE DSFL1dll; -// DSFL2dll_TYPE DSFL2dll; -// ENTHALdll_TYPE ENTHALdll; -// ENTROdll_TYPE ENTROdll; -// ESFLSHdll_TYPE ESFLSHdll; -// FGCTYdll_TYPE FGCTYdll; -// FPVdll_TYPE FPVdll; -// GERG04dll_TYPE GERG04dll; -// GETFIJdll_TYPE GETFIJdll; -// GETKTVdll_TYPE GETKTVdll; -// GIBBSdll_TYPE GIBBSdll; -// HSFLSHdll_TYPE HSFLSHdll; -// INFOdll_TYPE INFOdll; -// LIMITKdll_TYPE LIMITKdll; -// LIMITSdll_TYPE LIMITSdll; -// LIMITXdll_TYPE LIMITXdll; -// MELTPdll_TYPE MELTPdll; -// MELTTdll_TYPE MELTTdll; -// MLTH2Odll_TYPE MLTH2Odll; -// NAMEdll_TYPE NAMEdll; -// PDFL1dll_TYPE PDFL1dll; -// PDFLSHdll_TYPE PDFLSHdll; -// PEFLSHdll_TYPE PEFLSHdll; -// PHFL1dll_TYPE PHFL1dll; -// PHFLSHdll_TYPE PHFLSHdll; -// PQFLSHdll_TYPE PQFLSHdll; -// PREOSdll_TYPE PREOSdll; -// PRESSdll_TYPE PRESSdll; -// PSFL1dll_TYPE PSFL1dll; -// PSFLSHdll_TYPE PSFLSHdll; -// PUREFLDdll_TYPE PUREFLDdll; -// QMASSdll_TYPE QMASSdll; -// QMOLEdll_TYPE QMOLEdll; -// SATDdll_TYPE SATDdll; -// SATEdll_TYPE SATEdll; -// SATHdll_TYPE SATHdll; -// SATPdll_TYPE SATPdll; -// SATSdll_TYPE SATSdll; -// SATTdll_TYPE SATTdll; -// SETAGAdll_TYPE SETAGAdll; -// SETKTVdll_TYPE SETKTVdll; -// SETMIXdll_TYPE SETMIXdll; -// SETMODdll_TYPE SETMODdll; -// SETREFdll_TYPE SETREFdll; -// SETUPdll_TYPE SETUPdll; -//// SPECGRdll_TYPE SPECGRdll; // not found in library -// SUBLPdll_TYPE SUBLPdll; -// SUBLTdll_TYPE SUBLTdll; -// SURFTdll_TYPE SURFTdll; -// SURTENdll_TYPE SURTENdll; -// TDFLSHdll_TYPE TDFLSHdll; -// TEFLSHdll_TYPE TEFLSHdll; -// THERM0dll_TYPE THERM0dll; -// THERM2dll_TYPE THERM2dll; -// THERM3dll_TYPE THERM3dll; -// THERMdll_TYPE THERMdll; -// THFLSHdll_TYPE THFLSHdll; -// TPFLSHdll_TYPE TPFLSHdll; -// TPFL2dll_TYPE TPFL2dll; -// TPRHOdll_TYPE TPRHOdll; -// TQFLSHdll_TYPE TQFLSHdll; -// TRNPRPdll_TYPE TRNPRPdll; -// TSFLSHdll_TYPE TSFLSHdll; -// VIRBdll_TYPE VIRBdll; -// VIRCdll_TYPE VIRCdll; -// WMOLdll_TYPE WMOLdll; -// XMASSdll_TYPE XMASSdll; -// XMOLEdll_TYPE XMOLEdll; - // - // Define explicit function pointers - typedef RPVersion_TYPE * RPVersion_POINTER; - typedef SETPATHdll_TYPE * SETPATHdll_POINTER; - typedef ABFL1dll_TYPE * ABFL1dll_POINTER; - typedef ABFL2dll_TYPE * ABFL2dll_POINTER; - typedef ACTVYdll_TYPE * ACTVYdll_POINTER; - typedef AGdll_TYPE * AGdll_POINTER; - typedef CCRITdll_TYPE * CCRITdll_POINTER; - typedef CP0dll_TYPE * CP0dll_POINTER; - typedef CRITPdll_TYPE * CRITPdll_POINTER; - typedef CSATKdll_TYPE * CSATKdll_POINTER; - typedef CV2PKdll_TYPE * CV2PKdll_POINTER; - typedef CVCPKdll_TYPE * CVCPKdll_POINTER; - typedef CVCPdll_TYPE * CVCPdll_POINTER; - typedef DBDTdll_TYPE * DBDTdll_POINTER; - typedef DBFL1dll_TYPE * DBFL1dll_POINTER; - typedef DBFL2dll_TYPE * DBFL2dll_POINTER; - typedef DDDPdll_TYPE * DDDPdll_POINTER; - typedef DDDTdll_TYPE * DDDTdll_POINTER; - typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; - typedef DHD1dll_TYPE * DHD1dll_POINTER; - typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; - typedef DHFL1dll_TYPE * DHFL1dll_POINTER; - typedef DHFL2dll_TYPE * DHFL2dll_POINTER; - typedef DIELECdll_TYPE * DIELECdll_POINTER; - typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; - typedef DPDD2dll_TYPE * DPDD2dll_POINTER; - typedef DPDDKdll_TYPE * DPDDKdll_POINTER; - typedef DPDDdll_TYPE * DPDDdll_POINTER; - typedef DPDTKdll_TYPE * DPDTKdll_POINTER; - typedef DPDTdll_TYPE * DPDTdll_POINTER; - typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; - typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; - typedef DSFL1dll_TYPE * DSFL1dll_POINTER; - typedef DSFL2dll_TYPE * DSFL2dll_POINTER; - typedef ENTHALdll_TYPE * ENTHALdll_POINTER; - typedef ENTROdll_TYPE * ENTROdll_POINTER; - typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; - typedef FGCTYdll_TYPE * FGCTYdll_POINTER; - typedef FPVdll_TYPE * FPVdll_POINTER; - typedef GERG04dll_TYPE * GERG04dll_POINTER; - typedef GETFIJdll_TYPE * GETFIJdll_POINTER; - typedef GETKTVdll_TYPE * GETKTVdll_POINTER; - typedef GIBBSdll_TYPE * GIBBSdll_POINTER; - typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; - typedef INFOdll_TYPE * INFOdll_POINTER; - typedef LIMITKdll_TYPE * LIMITKdll_POINTER; - typedef LIMITSdll_TYPE * LIMITSdll_POINTER; - typedef LIMITXdll_TYPE * LIMITXdll_POINTER; - typedef MELTPdll_TYPE * MELTPdll_POINTER; - typedef MELTTdll_TYPE * MELTTdll_POINTER; - typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; - typedef NAMEdll_TYPE * NAMEdll_POINTER; - typedef PDFL1dll_TYPE * PDFL1dll_POINTER; - typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; - typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; - typedef PHFL1dll_TYPE * PHFL1dll_POINTER; - typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; - typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; - typedef PREOSdll_TYPE * PREOSdll_POINTER; - typedef PRESSdll_TYPE * PRESSdll_POINTER; - typedef PSFL1dll_TYPE * PSFL1dll_POINTER; - typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; - typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; - typedef QMASSdll_TYPE * QMASSdll_POINTER; - typedef QMOLEdll_TYPE * QMOLEdll_POINTER; - typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; - typedef SATDdll_TYPE * SATDdll_POINTER; - typedef SATEdll_TYPE * SATEdll_POINTER; - typedef SATHdll_TYPE * SATHdll_POINTER; - typedef SATPdll_TYPE * SATPdll_POINTER; - typedef SATSdll_TYPE * SATSdll_POINTER; - typedef SATTdll_TYPE * SATTdll_POINTER; - typedef SETAGAdll_TYPE * SETAGAdll_POINTER; - typedef SETKTVdll_TYPE * SETKTVdll_POINTER; - typedef SETMIXdll_TYPE * SETMIXdll_POINTER; - typedef SETMODdll_TYPE * SETMODdll_POINTER; - typedef SETREFdll_TYPE * SETREFdll_POINTER; - typedef SETUPdll_TYPE * SETUPdll_POINTER; -// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library - typedef SUBLPdll_TYPE * SUBLPdll_POINTER; - typedef SUBLTdll_TYPE * SUBLTdll_POINTER; - typedef SURFTdll_TYPE * SURFTdll_POINTER; - typedef SURTENdll_TYPE * SURTENdll_POINTER; - typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; - typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; - typedef THERM0dll_TYPE * THERM0dll_POINTER; - typedef THERM2dll_TYPE * THERM2dll_POINTER; - typedef THERM3dll_TYPE * THERM3dll_POINTER; - typedef THERMdll_TYPE * THERMdll_POINTER; - typedef THFLSHdll_TYPE * THFLSHdll_POINTER; - typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; - typedef TPFL2dll_TYPE * TPFL2dll_POINTER; - typedef TPRHOdll_TYPE * TPRHOdll_POINTER; - typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; - typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; - typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; - typedef VIRBdll_TYPE * VIRBdll_POINTER; - typedef VIRCdll_TYPE * VIRCdll_POINTER; - typedef WMOLdll_TYPE * WMOLdll_POINTER; - typedef XMASSdll_TYPE * XMASSdll_POINTER; - typedef XMOLEdll_TYPE * XMOLEdll_POINTER; -#if defined(__cplusplus) -} // extern "C" -#endif // __cplusplus -#endif // defined(RPversion) -#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 1b6c65e..ebcecad 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -612,7 +612,6 @@ double loadLibrary() { if (RefpropdllInstance == NULL) { // Refprop is not loaded #if defined(__ISWINDOWS__) #if defined(UNICODE) - //RefpropdllInstance = LoadLibrary((LPCWSTR)libName); RefpropdllInstance = LoadLibraryW((LPCWSTR)libName); #else RefpropdllInstance = LoadLibrary((LPCSTR)libName); @@ -804,6 +803,12 @@ double initRefprop() { printf("check types and names in header file.\n"); return FAIL; } + // Set the desired equation of state, consult the Refprop + // documentation for more details. + // 0 : use default values + // 2 : force Peng-Robinson + long eosSwitch = 0; + PREOSdll(eosSwitch); return OK; } else { if (debug) printf ("Library loaded, not doing anything.\n"); @@ -838,9 +843,6 @@ double setFluids(std::string sPath, std::string sFluids, char* error){ if (loadedFluids.compare(sFluids)) { // The fluid is not already loaded std::vector components_split = strsplit(sFluids,'|');// Split into components - - //printf ("%s \n",RefString.c_str()); - RefString.clear(); // Flush out fluid string // Build new fluid string @@ -981,7 +983,7 @@ double getS_modelica() { double getWM_modelica(){ //molecular weight - return dwm/1000; // g/mol to kg/mol + return dwm/1000; } double getDL_modelica(){ @@ -1367,12 +1369,6 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = -1. * ddhdp_d / ddhdd_p; ddddh_p = 1./ddhdd_p; } else { // two-phase region, get derivative of density with respect to enthalpy numerically - - - // TODO - ddddp_h = -1; - ddddh_p = -1; - /* if (debug) printf ("Using two-phase derivatives.\n"); deltaP = 0.00005; // 0.05 Pascal difference pLow = dp - 0.5*deltaP; @@ -1400,7 +1396,6 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); - */ } } else { // We have a problem! @@ -1679,7 +1674,7 @@ OUTPUT // Set variables to input values if ( strCompare(in1, in2) ) { sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return FAIL; + return -1; } memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; @@ -1912,15 +1907,12 @@ OUTPUT updateProps(props, lerr); + //int outVal = ders_REFPROP(ders,errormsg,debug); + //if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - // TODO - /* - int outVal = ders_REFPROP(ders,errormsg,debug); - if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + //outVal = trns_REFPROP(trns,errormsg,debug); + //if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - outVal = trns_REFPROP(trns,errormsg,debug); - if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - */ if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/src/refpropwrappertest.cpp deleted file mode 100644 index 483f5f2..0000000 --- a/_wrapper/src/refpropwrappertest.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include -#include -#include -#include -#include "refprop_wrapper.h" -#include "refprop_library.h" -#include -#include - - - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -int main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255]; - double* x; - double *props; - double *ders; - double *trns; - double sumx; - int i; -// int nX = argc-5; - int DEBUG = 0; - - - -/* - int count; - printf ("This program was called with \"%s\".\n",argv[0]); - if (argc > 1) - { - for (count = 1; count < argc; count++) - { - printf("argv[%d] = %s\n", count, argv[count]); - } - } - else - { - printf("The command had no other arguments.\n"); - } -printf("argc is %li \n",argc); -*/ - - -/* - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); -// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); - return 1; - } -*/ -// usage -// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 - -int nX=2; - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - ders=(double*) calloc(21,sizeof(double)); - trns=(double*) calloc(3,sizeof(double)); - -x[0] = 0.5; -x[1] = 1.0-x[0]; -//x[2] = 1-x[1]; - - - - - -/* - sumx = 0; - for (i=0;i Contact for original implementation: -Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" + annotation(version = "0.2", uses(Modelica(version = "3.2")), Documentation(info=" +

Documentation is found in the packages. Installation directions are found in both REFPROP packages.

+

Contact for original implementation:

+

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

+


Contact for this version:

+

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

+", + revisions = " ")); end REFPROP2Modelica; diff --git a/request b/request deleted file mode 100644 index 8d1c8b6..0000000 --- a/request +++ /dev/null @@ -1 +0,0 @@ - diff --git a/status b/status deleted file mode 100644 index 8d1c8b6..0000000 --- a/status +++ /dev/null @@ -1 +0,0 @@ - From 52948e1a5f85ed651644855bdb975e2bdf5004e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 26 Nov 2013 08:47:32 +0100 Subject: [PATCH 39/57] Revert "Revert "Some testing.."" This reverts commit b4a03bbc05985a368cd8faf841b0663a7de463c3. --- Examples.mo | 7 + Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 163 ++++- Media/NH3_Water.mo | 5 + Media/Pentane.mo | 5 + Media/R410mix.mo | 5 + Media/Water.mo | 5 + Media/package.order | 2 +- Testers/PropsMixtureNH3H2O.mo | 12 +- Testers/PropsMixtureTwo.mo | 13 +- Testers/PropsPureSubstance.mo | 6 +- Testers/R410mixTester.mo | 2 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 ++++++++ Testers/package.order | 1 + _wrapper/bin/refprop_library.h | 788 +++++++++++++++++++++ _wrapper/src/refprop_wrapper.cpp | 32 +- _wrapper/src/refpropwrappertest.cpp | 275 +++++++ package.mo | 29 +- request | 1 + status | 1 + 19 files changed, 1584 insertions(+), 54 deletions(-) create mode 100644 Examples.mo create mode 100644 Media/NH3_Water.mo create mode 100644 Media/Pentane.mo create mode 100644 Media/R410mix.mo create mode 100644 Media/Water.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT.mo create mode 100644 _wrapper/bin/refprop_library.h create mode 100644 _wrapper/src/refpropwrappertest.cpp create mode 100644 request create mode 100644 status diff --git a/Examples.mo b/Examples.mo new file mode 100644 index 0000000..a40086b --- /dev/null +++ b/Examples.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" +extends Modelica.Icons.ExamplesPackage; +annotation(preferedView="info", + __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", + "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); +end Examples; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 2286fc7..4f849d9 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -69,7 +69,7 @@ partial package REFPROPMixtureTwoPhaseMedium input String errormsg; // input Integer debug=1; output Real val; - external"C" val= props_REFPROP( + external "C" val= props_REFPROP( what2calc, statevars, fluidnames, @@ -100,6 +100,7 @@ partial package REFPROPMixtureTwoPhaseMedium algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); // Modelica.Utilities.Streams.print("Calc "+what2calc); + val := getProp_REFPROP( what2calc, statevars, @@ -112,6 +113,7 @@ partial package REFPROPMixtureTwoPhaseMedium X, phase, errormsg) "just passing through"; + // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); @@ -529,6 +531,36 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_phX; + redeclare function extends setBubbleState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(bubbleEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 0, + sat.X, + phase) ",fluidnames)"; + end setBubbleState; + + redeclare function extends setDewState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(dewEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 1, + sat.X, + phase) ",fluidnames)"; + end setDewState; + function setState_pqX "Calculates medium properties from p,q,X" extends Modelica.Icons.Function; input Modelica.SIunits.AbsolutePressure p "Pressure"; @@ -654,14 +686,34 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hv := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hv := getProp_REFPROP_check( - "h", + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", "pq", + fluidnames, + ders, + trns, + props, sat.psat, 1, sat.X, - 1); + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hv :=props[10]; + end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" @@ -678,26 +730,66 @@ end ThermodynamicState; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; + //algorithm + // dv := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 1); + extends partialREFPROP; + algorithm - dv := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 1, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 1, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dv :=props[5]; + end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hl := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hl := getProp_REFPROP_check( - "h", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hl :=props[10]; + end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" @@ -714,14 +806,35 @@ end ThermodynamicState; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; + //algorithm + // dl := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 1); + + extends partialREFPROP; + algorithm - dl := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dl :=props[5]; + end bubbleDensity; redeclare replaceable function extends molarMass diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo new file mode 100644 index 0000000..4ca5e00 --- /dev/null +++ b/Media/NH3_Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package NH3_Water "Ammonia and water mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"ammoniaL","water"}); +end NH3_Water; diff --git a/Media/Pentane.mo b/Media/Pentane.mo new file mode 100644 index 0000000..22d21a6 --- /dev/null +++ b/Media/Pentane.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Pentane "Pentane from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"pentane"}); +end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo new file mode 100644 index 0000000..1d03112 --- /dev/null +++ b/Media/R410mix.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); +end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo new file mode 100644 index 0000000..67db3b5 --- /dev/null +++ b/Media/Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"water"}); +end Water; diff --git a/Media/package.order b/Media/package.order index 453f582..5841ec9 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,4 +1,4 @@ Pentane R410mix -R410 Water +NH3_Water diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 0292e7b..7a255ab 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; model PropsMixtureNH3H2O package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammonia","water"}, + final substanceNames={"ammoniaL","water"}, inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); Medium.ThermodynamicState state; @@ -13,6 +13,14 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; + Medium.SaturationProperties sat = Medium.setSat_pX(p,X); + + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + protected Modelica.SIunits.Temperature T_init = 400; Real[2] X_init = {0.5,0.5}; @@ -25,6 +33,8 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); + p = Medium.pressure(state); q = Medium.vapourQuality(state); + end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index 7b79646..a13a30c 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -8,8 +8,19 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Real q = Medium.vapourQuality(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); + + Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + + Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); + Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); + equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {0.5}; + props.Xi = {.5}; + end PropsMixtureTwo; diff --git a/Testers/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo index e23b4a8..94d9161 100644 --- a/Testers/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -5,7 +5,7 @@ model PropsPureSubstance //package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); //package Medium = REFPROPMedium(final substanceNames={"ammonia"}); //package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); +package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); Medium.BaseProperties props; @@ -15,14 +15,14 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final // Modelica.SIunits.SpecificEnthalpy h; // Modelica.SIunits.SpecificEntropy s; // Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); // Modelica.SIunits.MolarMass MM; Real q= Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; // Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); // Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); equation props.p = 1e5 "sine_p.y"; props.h = 0+time*722774; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo index c28c7c3..96f0283 100644 --- a/Testers/R410mixTester.mo +++ b/Testers/R410mixTester.mo @@ -1,6 +1,6 @@ within REFPROP2Modelica.Testers; model R410mixTester "Density of saturated R410 vapour" -package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); +package Medium = REFPROP2Modelica.Media.R410mix; Medium.BaseProperties props; Medium.Density d; Medium.SpecificEnthalpy h(start=300e3); diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo new file mode 100644 index 0000000..deb20fd --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -0,0 +1,286 @@ +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT + "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( + final mediumName="TwoPhaseMixtureWater", + final substanceNames={"water"}, + final reducedX = true, + final singleState=false, + reference_X=cat(1,fill(0,nX-1),{1}), + fluidConstants = BrineConstants); +// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + redeclare model extends BaseProperties "Base properties of medium" + Real GVF=q*d/d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case + equation + u = h - p/d; + MM = M_H2O; + R = Modelica.Constants.R/MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p,T,X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei gesättigter Lösung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s=0 "TODO"; + state = ThermodynamicState( + p=p, + T=T, + X=X, + X_l=X, + h=h, + GVF=GVF, + q=q, + s=0, + d_g=d_g, + d_l=d_l, + d=d, + phase=0) "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation (Documentation(info=""), + Documentation(revisions=" + +")); + end BaseProperties; + + redeclare function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); + algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); + end specificEnthalpy_pTX; + + redeclare function temperature_phX + "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); + algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); + end temperature_phX; + +redeclare record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" +/* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start=300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start=300) "density liquid phase"; + Density d_g(start=300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation (Documentation(info=" + +")); +end ThermodynamicState; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" + algorithm + hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); + end dewEnthalpy; + + redeclare function extends bubbleEnthalpy + "boiling curve specific enthalpy of water" + algorithm + hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); + end bubbleEnthalpy; + + redeclare function extends saturationTemperature + algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); + end saturationTemperature; + + redeclare function extends dynamicViscosity + algorithm + eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); + end dynamicViscosity; + +redeclare function extends specificEntropy "specific entropy of water" +algorithm + s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + +redeclare function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + +redeclare function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state := ThermodynamicState( + d=density_ps(p,s), + T=temperature_ps(p,s), + phase=0, + h=specificEnthalpy_ps(p,s), + p=p, + X=X, + s=s, + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_psX; + + redeclare function extends temperature "return temperature of ideal gas" + algorithm + T := state.T; + end temperature; + + redeclare function extends density "return density of ideal gas" + algorithm + d := state.d; + end density; + +redeclare function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state := ThermodynamicState( + d=density_pT(p,T), + T=T, + phase=0, + h=specificEnthalpy_pTX(p,s), + p=p, + X=X, + s=specificEntropy_pT(p.T), + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_pTX; + +redeclare function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + + redeclare function extends thermalConductivity + "Thermal conductivity of water" + algorithm + lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( + state.d, + state.T, + state.p, + state.phase); + end thermalConductivity; + + redeclare function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp := Modelica.Media.Water.IF97_Utilities.cp_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCp; + + redeclare function extends saturationPressure + algorithm + p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); + end saturationPressure; + + redeclare function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv := Modelica.Media.Water.IF97_Utilities.cv_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCv; + + annotation (Documentation(info=" +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index 1b48ebf..cbda809 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,4 +3,5 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester +Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h new file mode 100644 index 0000000..5231ae8 --- /dev/null +++ b/_wrapper/bin/refprop_library.h @@ -0,0 +1,788 @@ + +#ifndef REFPROP_LIB_H +#define REFPROP_LIB_H + +/* +// The idea here is to have a common header for Windows +// and gcc-like systems. The Windows branch should cover the +// functions provided by the .dll and the gcc part covers +// the compiled .so/.dym file. Name changes caused by gfortran +// are respected and should be accounted for. +*/ +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +// Do some manual changes to the function names +// if needed, uses CoolProp platform detection. +#if defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV __stdcall +// Do not redefine function names for the shared library, +// in this case it is the REFPROP.dll and no special +// names are needed. Macros still need a value for the +// name function used below. +# define RPVersion RPVersion +# define SETPATHdll SETPATHdll +# define ABFL1dll ABFL1dll +# define ABFL2dll ABFL2dll +# define ACTVYdll ACTVYdll +# define AGdll AGdll +# define CCRITdll CCRITdll +# define CP0dll CP0dll +# define CRITPdll CRITPdll +# define CSATKdll CSATKdll +# define CV2PKdll CV2PKdll +# define CVCPKdll CVCPKdll +# define CVCPdll CVCPdll +# define DBDTdll DBDTdll +# define DBFL1dll DBFL1dll +# define DBFL2dll DBFL2dll +# define DDDPdll DDDPdll +# define DDDTdll DDDTdll +# define DEFLSHdll DEFLSHdll +# define DHD1dll DHD1dll +# define DHFL1dll DHFL1dll +# define DHFL2dll DHFL2dll +# define DHFLSHdll DHFLSHdll +# define DIELECdll DIELECdll +# define DOTFILLdll DOTFILLdll +# define DPDD2dll DPDD2dll +# define DPDDKdll DPDDKdll +# define DPDDdll DPDDdll +# define DPDTKdll DPDTKdll +# define DPDTdll DPDTdll +# define DPTSATKdll DPTSATKdll +# define DSFLSHdll DSFLSHdll +# define DSFL1dll DSFL1dll +# define DSFL2dll DSFL2dll +# define ENTHALdll ENTHALdll +# define ENTROdll ENTROdll +# define ESFLSHdll ESFLSHdll +# define FGCTYdll FGCTYdll +# define FPVdll FPVdll +# define GERG04dll GERG04dll +# define GETFIJdll GETFIJdll +# define GETKTVdll GETKTVdll +# define GIBBSdll GIBBSdll +# define HSFLSHdll HSFLSHdll +# define INFOdll INFOdll +# define LIMITKdll LIMITKdll +# define LIMITSdll LIMITSdll +# define LIMITXdll LIMITXdll +# define MELTPdll MELTPdll +# define MELTTdll MELTTdll +# define MLTH2Odll MLTH2Odll +# define NAMEdll NAMEdll +# define PDFL1dll PDFL1dll +# define PDFLSHdll PDFLSHdll +# define PEFLSHdll PEFLSHdll +# define PHFL1dll PHFL1dll +# define PHFLSHdll PHFLSHdll +# define PQFLSHdll PQFLSHdll +# define PREOSdll PREOSdll +# define PRESSdll PRESSdll +# define PSFL1dll PSFL1dll +# define PSFLSHdll PSFLSHdll +# define PUREFLDdll PUREFLDdll +# define QMASSdll QMASSdll +# define QMOLEdll QMOLEdll +# define RESIDUALdll RESIDUALdll +# define SATDdll SATDdll +# define SATEdll SATEdll +# define SATHdll SATHdll +# define SATPdll SATPdll +# define SATSdll SATSdll +# define SATTdll SATTdll +# define SETAGAdll SETAGAdll +# define SETKTVdll SETKTVdll +# define SETMIXdll SETMIXdll +# define SETMODdll SETMODdll +# define SETREFdll SETREFdll +# define SETUPdll SETUPdll +//# define SPECGRdll SPECGRdll // not found in library +# define SUBLPdll SUBLPdll +# define SUBLTdll SUBLTdll +# define SURFTdll SURFTdll +# define SURTENdll SURTENdll +# define TDFLSHdll TDFLSHdll +# define TEFLSHdll TEFLSHdll +# define THERM0dll THERM0dll +# define THERM2dll THERM2dll +# define THERM3dll THERM3dll +# define THERMdll THERMdll +# define THFLSHdll THFLSHdll +# define TPFLSHdll TPFLSHdll +# define TPFL2dll TPFL2dll +# define TPRHOdll TPRHOdll +# define TQFLSHdll TQFLSHdll +# define TRNPRPdll TRNPRPdll +# define TSFLSHdll TSFLSHdll +# define VIRBdll VIRBdll +# define VIRCdll VIRCdll +# define WMOLdll WMOLdll +# define XMASSdll XMASSdll +# define XMOLEdll XMOLEdll +#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) +// Define compiler specific calling conventions +// for the shared library. +# define CALLCONV +// Define function names for the shared library, +// in this case it is the librefprop.so and the +// names might change on some systems during +// the compilation of the Fortran files. +// Possible other branches for this code could be: +// # if !defined(_AIX) +// # if !defined(__hpux) +// # if defined( _CRAY +// However, I cannot test that and therefore do not include it. +# define RPVersion rpversion_ +# define SETPATHdll setpathdll_ +# define ABFL1dll abfl1dll_ +# define ABFL2dll abfl2dll_ +# define ACTVYdll actvydll_ +# define AGdll agdll_ +# define CCRITdll ccritdll_ +# define CP0dll cp0dll_ +# define CRITPdll critpdll_ +# define CSATKdll csatkdll_ +# define CV2PKdll cv2pkdll_ +# define CVCPKdll cvcpkdll_ +# define CVCPdll cvcpdll_ +# define DBDTdll dbdtdll_ +# define DBFL1dll dbfl1dll_ +# define DBFL2dll dbfl2dll_ +# define DDDPdll dddpdll_ +# define DDDTdll dddtdll_ +# define DEFLSHdll deflshdll_ +# define DHD1dll dhd1dll_ +# define DHFL1dll dhfl1dll_ +# define DHFL2dll dhfl2dll_ +# define DHFLSHdll dhflshdll_ +# define DIELECdll dielecdll_ +# define DOTFILLdll dotfilldll_ +# define DPDD2dll dpdd2dll_ +# define DPDDKdll dpddkdll_ +# define DPDDdll dpdddll_ +# define DPDTKdll dpdtkdll_ +# define DPDTdll dpdtdll_ +# define DPTSATKdll dptsatkdll_ +# define DSFLSHdll dsflshdll_ +# define DSFL1dll dsfl1dll_ +# define DSFL2dll dsfl2dll_ +# define ENTHALdll enthaldll_ +# define ENTROdll entrodll_ +# define ESFLSHdll esflshdll_ +# define FGCTYdll fgctydll_ +# define FPVdll fpvdll_ +# define GERG04dll gerg04dll_ +# define GETFIJdll getfijdll_ +# define GETKTVdll getktvdll_ +# define GIBBSdll gibbsdll_ +# define HSFLSHdll hsflshdll_ +# define INFOdll infodll_ +# define LIMITKdll limitkdll_ +# define LIMITSdll limitsdll_ +# define LIMITXdll limitxdll_ +# define MELTPdll meltpdll_ +# define MELTTdll melttdll_ +# define MLTH2Odll mlth2odll_ +# define NAMEdll namedll_ +# define PDFL1dll pdfl1dll_ +# define PDFLSHdll pdflshdll_ +# define PEFLSHdll peflshdll_ +# define PHFL1dll phfl1dll_ +# define PHFLSHdll phflshdll_ +# define PQFLSHdll pqflshdll_ +# define PREOSdll preosdll_ +# define PRESSdll pressdll_ +# define PSFL1dll psfl1dll_ +# define PSFLSHdll psflshdll_ +# define PUREFLDdll pureflddll_ +# define QMASSdll qmassdll_ +# define QMOLEdll qmoledll_ +# define RESIDUALdll residualdll_ +# define SATDdll satddll_ +# define SATEdll satedll_ +# define SATHdll sathdll_ +# define SATPdll satpdll_ +# define SATSdll satsdll_ +# define SATTdll sattdll_ +# define SETAGAdll setagadll_ +# define SETKTVdll setktvdll_ +# define SETMIXdll setmixdll_ +# define SETMODdll setmoddll_ +# define SETREFdll setrefdll_ +# define SETUPdll setupdll_ +//# define SPECGRdll specgrdll_ // not found in library +# define SUBLPdll sublpdll_ +# define SUBLTdll subltdll_ +# define SURFTdll surftdll_ +# define SURTENdll surtendll_ +# define TDFLSHdll tdflshdll_ +# define TEFLSHdll teflshdll_ +# define THERM0dll therm0dll_ +# define THERM2dll therm2dll_ +# define THERM3dll therm3dll_ +# define THERMdll thermdll_ +# define THFLSHdll thflshdll_ +# define TPFLSHdll tpflshdll_ +# define TPFL2dll tpfl2dll_ +# define TPRHOdll tprhodll_ +# define TQFLSHdll tqflshdll_ +# define TRNPRPdll trnprpdll_ +# define TSFLSHdll tsflshdll_ +# define VIRBdll virbdll_ +# define VIRCdll vircdll_ +# define WMOLdll wmoldll_ +# define XMASSdll xmassdll_ +# define XMOLEdll xmoledll_ +#else // #elif defined(__ISLINUX__) +// Set some dummy names for the compiler +# define CALLCONV +# define RPVersion NOTAVAILABLE +# define SETPATHdll setpathdll +# define ABFL1dll abfl1dll +# define ABFL2dll abfl2dll +# define ACTVYdll actvydll +# define AGdll agdll +# define CCRITdll ccritdll +# define CP0dll cp0dll +# define CRITPdll critpdll +# define CSATKdll csatkdll +# define CV2PKdll cv2pkdll +# define CVCPKdll cvcpkdll +# define CVCPdll cvcpdll +# define DBDTdll dbdtdll +# define DBFL1dll dbfl1dll +# define DBFL2dll dbfl2dll +# define DDDPdll dddpdll +# define DDDTdll dddtdll +# define DEFLSHdll deflshdll +# define DHD1dll dhd1dll +# define DHFL1dll dhfl1dll +# define DHFL2dll dhfl2dll +# define DHFLSHdll dhflshdll +# define DIELECdll dielecdll +# define DOTFILLdll dotfilldll +# define DPDD2dll dpdd2dll +# define DPDDKdll dpddkdll +# define DPDDdll dpdddll +# define DPDTKdll dpdtkdll +# define DPDTdll dpdtdll +# define DPTSATKdll dptsatkdll +# define DSFLSHdll dsflshdll +# define DSFL1dll dsfl1dll +# define DSFL2dll dsfl2dll +# define ENTHALdll enthaldll +# define ENTROdll entrodll +# define ESFLSHdll esflshdll +# define FGCTYdll fgctydll +# define FPVdll fpvdll +# define GERG04dll gerg04dll +# define GETFIJdll getfijdll +# define GETKTVdll getktvdll +# define GIBBSdll gibbsdll +# define HSFLSHdll hsflshdll +# define INFOdll infodll +# define LIMITKdll limitkdll +# define LIMITSdll limitsdll +# define LIMITXdll limitxdll +# define MELTPdll meltpdll +# define MELTTdll melttdll +# define MLTH2Odll mlth2odll +# define NAMEdll namedll +# define PDFL1dll pdfl1dll +# define PDFLSHdll pdflshdll +# define PEFLSHdll peflshdll +# define PHFL1dll phfl1dll +# define PHFLSHdll phflshdll +# define PQFLSHdll pqflshdll +# define PREOSdll preosdll +# define PRESSdll pressdll +# define PSFL1dll psfl1dll +# define PSFLSHdll psflshdll +# define PUREFLDdll pureflddll +# define QMASSdll qmassdll +# define QMOLEdll qmoledll +# define RESIDUALdll residualdll +# define SATDdll satddll +# define SATEdll satedll +# define SATHdll sathdll +# define SATPdll satpdll +# define SATSdll satsdll +# define SATTdll sattdll +# define SETAGAdll setagadll +# define SETKTVdll setktvdll +# define SETMIXdll setmixdll +# define SETMODdll setmoddll +# define SETREFdll setrefdll +# define SETUPdll setupdll +//# define SPECGRdll specgrdll // not found in library +# define SUBLPdll sublpdll +# define SUBLTdll subltdll +# define SURFTdll surftdll +# define SURTENdll surtendll +# define TDFLSHdll tdflshdll +# define TEFLSHdll teflshdll +# define THERM0dll therm0dll +# define THERM2dll therm2dll +# define THERM3dll therm3dll +# define THERMdll thermdll +# define THFLSHdll thflshdll +# define TPFLSHdll tpflshdll +# define TPFL2dll tpfl2dll +# define TPRHOdll tprhodll +# define TQFLSHdll tqflshdll +# define TRNPRPdll trnprpdll +# define TSFLSHdll tsflshdll +# define VIRBdll virbdll +# define VIRCdll vircdll +# define WMOLdll wmoldll +# define XMASSdll xmassdll +# define XMOLEdll xmoledll +#endif // else branch +// +// +// Only continue if function names have been defined. +// We might want to include some more tests here... +#if defined(RPVersion) +// define new macros for function names +// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value +#include +#include +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) +// +// Prepare the strings to be used by the functions that +// handle the library later on. +#define RPVersion_NAME FUNCTION_NAME(RPVersion) +#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) +#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) +#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) +#define AGdll_NAME FUNCTION_NAME(AGdll) +#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) +#define CP0dll_NAME FUNCTION_NAME(CP0dll) +#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) +#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) +#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) +#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) +#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) +#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) +#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) +#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) +#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) +#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) +#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) +#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) +#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) +#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) +#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) +#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) +#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) +#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) +#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) +#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) +#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) +#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) +#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) +#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) +#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) +#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) +#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) +#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) +#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) +#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) +#define FPVdll_NAME FUNCTION_NAME(FPVdll) +#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) +#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) +#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) +#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) +#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) +#define INFOdll_NAME FUNCTION_NAME(INFOdll) +#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) +#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) +#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) +#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) +#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) +#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) +#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) +#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) +#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) +#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) +#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) +#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) +#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) +#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) +#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) +#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) +#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) +#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) +#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) +#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) +#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) +#define SATDdll_NAME FUNCTION_NAME(SATDdll) +#define SATEdll_NAME FUNCTION_NAME(SATEdll) +#define SATHdll_NAME FUNCTION_NAME(SATHdll) +#define SATPdll_NAME FUNCTION_NAME(SATPdll) +#define SATSdll_NAME FUNCTION_NAME(SATSdll) +#define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) +#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) +#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) +#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) +#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) +#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) +//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library +#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) +#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) +#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) +#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) +#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) +#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) +#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) +#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) +#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) +#define THERMdll_NAME FUNCTION_NAME(THERMdll) +#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) +#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) +#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) +#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) +#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) +#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) +#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) +#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) +#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) +#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) +#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) +#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) +// +// I'll try to follow this example from: +// http://www.gershnik.com/tips/cpp.asp +// function type: typedef void [compiler stuff] func_t(int, float); +// function declaration: func_t func; +// pointer type: typedef func_t * func_ptr; +#if defined(__cplusplus) +extern "C" { +#endif + typedef void (CALLCONV RPVersion_TYPE)( char* ); + typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + // + typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); + typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); + typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); + typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); + typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); + typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); + typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); + typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); + typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); + typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); + typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); + typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PREOSdll_TYPE)(long &); + typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); + typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV PUREFLDdll_TYPE)(long &); + typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); + typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); + typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); + typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); + typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); + typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); + typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); + typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); + typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); + typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); + typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); + typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); + typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); + typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); + typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); + typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); +// +// Disabled because we prefer pointers here! +// // Declare the functions for direct access, +// RPVersion_TYPE RPVersion; +// SETPATHdll_TYPE SETPATHdll; +// ABFL1dll_TYPE ABFL1dll; +// ABFL2dll_TYPE ABFL2dll; +// ACTVYdll_TYPE ACTVYdll; +// AGdll_TYPE AGdll; +// CCRITdll_TYPE CCRITdll; +// CP0dll_TYPE CP0dll; +// CRITPdll_TYPE CRITPdll; +// CSATKdll_TYPE CSATKdll; +// CV2PKdll_TYPE CV2PKdll; +// CVCPKdll_TYPE CVCPKdll; +// CVCPdll_TYPE CVCPdll; +// DBDTdll_TYPE DBDTdll; +// DBFL1dll_TYPE DBFL1dll; +// DBFL2dll_TYPE DBFL2dll; +// DDDPdll_TYPE DDDPdll; +// DDDTdll_TYPE DDDTdll; +// DEFLSHdll_TYPE DEFLSHdll; +// DHD1dll_TYPE DHD1dll; +// DHFLSHdll_TYPE DHFLSHdll; +// DHFL1dll_TYPE DHFL1dll; +// DHFL2dll_TYPE DHFL2dll; +// DIELECdll_TYPE DIELECdll; +// DOTFILLdll_TYPE DOTFILLdll; +// DPDD2dll_TYPE DPDD2dll; +// DPDDKdll_TYPE DPDDKdll; +// DPDDdll_TYPE DPDDdll; +// DPDTKdll_TYPE DPDTKdll; +// DPDTdll_TYPE DPDTdll; +// DPTSATKdll_TYPE DPTSATKdll; +// DSFLSHdll_TYPE DSFLSHdll; +// DSFL1dll_TYPE DSFL1dll; +// DSFL2dll_TYPE DSFL2dll; +// ENTHALdll_TYPE ENTHALdll; +// ENTROdll_TYPE ENTROdll; +// ESFLSHdll_TYPE ESFLSHdll; +// FGCTYdll_TYPE FGCTYdll; +// FPVdll_TYPE FPVdll; +// GERG04dll_TYPE GERG04dll; +// GETFIJdll_TYPE GETFIJdll; +// GETKTVdll_TYPE GETKTVdll; +// GIBBSdll_TYPE GIBBSdll; +// HSFLSHdll_TYPE HSFLSHdll; +// INFOdll_TYPE INFOdll; +// LIMITKdll_TYPE LIMITKdll; +// LIMITSdll_TYPE LIMITSdll; +// LIMITXdll_TYPE LIMITXdll; +// MELTPdll_TYPE MELTPdll; +// MELTTdll_TYPE MELTTdll; +// MLTH2Odll_TYPE MLTH2Odll; +// NAMEdll_TYPE NAMEdll; +// PDFL1dll_TYPE PDFL1dll; +// PDFLSHdll_TYPE PDFLSHdll; +// PEFLSHdll_TYPE PEFLSHdll; +// PHFL1dll_TYPE PHFL1dll; +// PHFLSHdll_TYPE PHFLSHdll; +// PQFLSHdll_TYPE PQFLSHdll; +// PREOSdll_TYPE PREOSdll; +// PRESSdll_TYPE PRESSdll; +// PSFL1dll_TYPE PSFL1dll; +// PSFLSHdll_TYPE PSFLSHdll; +// PUREFLDdll_TYPE PUREFLDdll; +// QMASSdll_TYPE QMASSdll; +// QMOLEdll_TYPE QMOLEdll; +// SATDdll_TYPE SATDdll; +// SATEdll_TYPE SATEdll; +// SATHdll_TYPE SATHdll; +// SATPdll_TYPE SATPdll; +// SATSdll_TYPE SATSdll; +// SATTdll_TYPE SATTdll; +// SETAGAdll_TYPE SETAGAdll; +// SETKTVdll_TYPE SETKTVdll; +// SETMIXdll_TYPE SETMIXdll; +// SETMODdll_TYPE SETMODdll; +// SETREFdll_TYPE SETREFdll; +// SETUPdll_TYPE SETUPdll; +//// SPECGRdll_TYPE SPECGRdll; // not found in library +// SUBLPdll_TYPE SUBLPdll; +// SUBLTdll_TYPE SUBLTdll; +// SURFTdll_TYPE SURFTdll; +// SURTENdll_TYPE SURTENdll; +// TDFLSHdll_TYPE TDFLSHdll; +// TEFLSHdll_TYPE TEFLSHdll; +// THERM0dll_TYPE THERM0dll; +// THERM2dll_TYPE THERM2dll; +// THERM3dll_TYPE THERM3dll; +// THERMdll_TYPE THERMdll; +// THFLSHdll_TYPE THFLSHdll; +// TPFLSHdll_TYPE TPFLSHdll; +// TPFL2dll_TYPE TPFL2dll; +// TPRHOdll_TYPE TPRHOdll; +// TQFLSHdll_TYPE TQFLSHdll; +// TRNPRPdll_TYPE TRNPRPdll; +// TSFLSHdll_TYPE TSFLSHdll; +// VIRBdll_TYPE VIRBdll; +// VIRCdll_TYPE VIRCdll; +// WMOLdll_TYPE WMOLdll; +// XMASSdll_TYPE XMASSdll; +// XMOLEdll_TYPE XMOLEdll; + // + // Define explicit function pointers + typedef RPVersion_TYPE * RPVersion_POINTER; + typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef ABFL1dll_TYPE * ABFL1dll_POINTER; + typedef ABFL2dll_TYPE * ABFL2dll_POINTER; + typedef ACTVYdll_TYPE * ACTVYdll_POINTER; + typedef AGdll_TYPE * AGdll_POINTER; + typedef CCRITdll_TYPE * CCRITdll_POINTER; + typedef CP0dll_TYPE * CP0dll_POINTER; + typedef CRITPdll_TYPE * CRITPdll_POINTER; + typedef CSATKdll_TYPE * CSATKdll_POINTER; + typedef CV2PKdll_TYPE * CV2PKdll_POINTER; + typedef CVCPKdll_TYPE * CVCPKdll_POINTER; + typedef CVCPdll_TYPE * CVCPdll_POINTER; + typedef DBDTdll_TYPE * DBDTdll_POINTER; + typedef DBFL1dll_TYPE * DBFL1dll_POINTER; + typedef DBFL2dll_TYPE * DBFL2dll_POINTER; + typedef DDDPdll_TYPE * DDDPdll_POINTER; + typedef DDDTdll_TYPE * DDDTdll_POINTER; + typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; + typedef DHD1dll_TYPE * DHD1dll_POINTER; + typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; + typedef DHFL1dll_TYPE * DHFL1dll_POINTER; + typedef DHFL2dll_TYPE * DHFL2dll_POINTER; + typedef DIELECdll_TYPE * DIELECdll_POINTER; + typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; + typedef DPDD2dll_TYPE * DPDD2dll_POINTER; + typedef DPDDKdll_TYPE * DPDDKdll_POINTER; + typedef DPDDdll_TYPE * DPDDdll_POINTER; + typedef DPDTKdll_TYPE * DPDTKdll_POINTER; + typedef DPDTdll_TYPE * DPDTdll_POINTER; + typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; + typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; + typedef DSFL1dll_TYPE * DSFL1dll_POINTER; + typedef DSFL2dll_TYPE * DSFL2dll_POINTER; + typedef ENTHALdll_TYPE * ENTHALdll_POINTER; + typedef ENTROdll_TYPE * ENTROdll_POINTER; + typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; + typedef FGCTYdll_TYPE * FGCTYdll_POINTER; + typedef FPVdll_TYPE * FPVdll_POINTER; + typedef GERG04dll_TYPE * GERG04dll_POINTER; + typedef GETFIJdll_TYPE * GETFIJdll_POINTER; + typedef GETKTVdll_TYPE * GETKTVdll_POINTER; + typedef GIBBSdll_TYPE * GIBBSdll_POINTER; + typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; + typedef INFOdll_TYPE * INFOdll_POINTER; + typedef LIMITKdll_TYPE * LIMITKdll_POINTER; + typedef LIMITSdll_TYPE * LIMITSdll_POINTER; + typedef LIMITXdll_TYPE * LIMITXdll_POINTER; + typedef MELTPdll_TYPE * MELTPdll_POINTER; + typedef MELTTdll_TYPE * MELTTdll_POINTER; + typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; + typedef NAMEdll_TYPE * NAMEdll_POINTER; + typedef PDFL1dll_TYPE * PDFL1dll_POINTER; + typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; + typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; + typedef PHFL1dll_TYPE * PHFL1dll_POINTER; + typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; + typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; + typedef PREOSdll_TYPE * PREOSdll_POINTER; + typedef PRESSdll_TYPE * PRESSdll_POINTER; + typedef PSFL1dll_TYPE * PSFL1dll_POINTER; + typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; + typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; + typedef QMASSdll_TYPE * QMASSdll_POINTER; + typedef QMOLEdll_TYPE * QMOLEdll_POINTER; + typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; + typedef SATDdll_TYPE * SATDdll_POINTER; + typedef SATEdll_TYPE * SATEdll_POINTER; + typedef SATHdll_TYPE * SATHdll_POINTER; + typedef SATPdll_TYPE * SATPdll_POINTER; + typedef SATSdll_TYPE * SATSdll_POINTER; + typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SETAGAdll_TYPE * SETAGAdll_POINTER; + typedef SETKTVdll_TYPE * SETKTVdll_POINTER; + typedef SETMIXdll_TYPE * SETMIXdll_POINTER; + typedef SETMODdll_TYPE * SETMODdll_POINTER; + typedef SETREFdll_TYPE * SETREFdll_POINTER; + typedef SETUPdll_TYPE * SETUPdll_POINTER; +// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library + typedef SUBLPdll_TYPE * SUBLPdll_POINTER; + typedef SUBLTdll_TYPE * SUBLTdll_POINTER; + typedef SURFTdll_TYPE * SURFTdll_POINTER; + typedef SURTENdll_TYPE * SURTENdll_POINTER; + typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; + typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; + typedef THERM0dll_TYPE * THERM0dll_POINTER; + typedef THERM2dll_TYPE * THERM2dll_POINTER; + typedef THERM3dll_TYPE * THERM3dll_POINTER; + typedef THERMdll_TYPE * THERMdll_POINTER; + typedef THFLSHdll_TYPE * THFLSHdll_POINTER; + typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; + typedef TPFL2dll_TYPE * TPFL2dll_POINTER; + typedef TPRHOdll_TYPE * TPRHOdll_POINTER; + typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; + typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; + typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; + typedef VIRBdll_TYPE * VIRBdll_POINTER; + typedef VIRCdll_TYPE * VIRCdll_POINTER; + typedef WMOLdll_TYPE * WMOLdll_POINTER; + typedef XMASSdll_TYPE * XMASSdll_POINTER; + typedef XMOLEdll_TYPE * XMOLEdll_POINTER; +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus +#endif // defined(RPversion) +#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index ebcecad..1b6c65e 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -612,6 +612,7 @@ double loadLibrary() { if (RefpropdllInstance == NULL) { // Refprop is not loaded #if defined(__ISWINDOWS__) #if defined(UNICODE) + //RefpropdllInstance = LoadLibrary((LPCWSTR)libName); RefpropdllInstance = LoadLibraryW((LPCWSTR)libName); #else RefpropdllInstance = LoadLibrary((LPCSTR)libName); @@ -803,12 +804,6 @@ double initRefprop() { printf("check types and names in header file.\n"); return FAIL; } - // Set the desired equation of state, consult the Refprop - // documentation for more details. - // 0 : use default values - // 2 : force Peng-Robinson - long eosSwitch = 0; - PREOSdll(eosSwitch); return OK; } else { if (debug) printf ("Library loaded, not doing anything.\n"); @@ -843,6 +838,9 @@ double setFluids(std::string sPath, std::string sFluids, char* error){ if (loadedFluids.compare(sFluids)) { // The fluid is not already loaded std::vector components_split = strsplit(sFluids,'|');// Split into components + + //printf ("%s \n",RefString.c_str()); + RefString.clear(); // Flush out fluid string // Build new fluid string @@ -983,7 +981,7 @@ double getS_modelica() { double getWM_modelica(){ //molecular weight - return dwm/1000; + return dwm/1000; // g/mol to kg/mol } double getDL_modelica(){ @@ -1369,6 +1367,12 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = -1. * ddhdp_d / ddhdd_p; ddddh_p = 1./ddhdd_p; } else { // two-phase region, get derivative of density with respect to enthalpy numerically + + + // TODO + ddddp_h = -1; + ddddh_p = -1; + /* if (debug) printf ("Using two-phase derivatives.\n"); deltaP = 0.00005; // 0.05 Pascal difference pLow = dp - 0.5*deltaP; @@ -1396,6 +1400,7 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + */ } } else { // We have a problem! @@ -1674,7 +1679,7 @@ OUTPUT // Set variables to input values if ( strCompare(in1, in2) ) { sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return -1; + return FAIL; } memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; @@ -1907,12 +1912,15 @@ OUTPUT updateProps(props, lerr); - //int outVal = ders_REFPROP(ders,errormsg,debug); - //if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - //outVal = trns_REFPROP(trns,errormsg,debug); - //if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + // TODO + /* + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + */ if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/src/refpropwrappertest.cpp new file mode 100644 index 0000000..483f5f2 --- /dev/null +++ b/_wrapper/src/refpropwrappertest.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;iContact for original implementation:

-

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

-


Contact for this version:

-

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

-", - revisions = " + + annotation (version="0.2", uses(Modelica(version="3.2")), + Documentation(info=" +

+Documentation is found in the packages. Installation directions are found in both REFPROP packages. +

+

Contact for original implementation:

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +", + revisions=" ")); end REFPROP2Modelica; diff --git a/request b/request new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/request @@ -0,0 +1 @@ + diff --git a/status b/status new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/status @@ -0,0 +1 @@ + From 9e3a154b3012bad3228679c1ffbc6f10fba06bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 26 Nov 2013 08:52:24 +0100 Subject: [PATCH 40/57] Trying to learn things.. Some testing.. (reverted from commit 368df8a142cc335d59294aee095138904a564f3f) --- Examples.mo | 7 - Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 163 +--- Media/NH3_Water.mo | 5 - Media/Pentane.mo | 5 - Media/R410mix.mo | 5 - Media/Water.mo | 5 - Media/package.order | 2 +- Testers/PropsMixtureNH3H2O.mo | 12 +- Testers/PropsMixtureTwo.mo | 13 +- Testers/PropsPureSubstance.mo | 6 +- Testers/R410mixTester.mo | 2 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 ------- Testers/package.order | 1 - _wrapper/bin/refprop_library.h | 788 ------------------ .../refpropwrappertest_new.cpp} | 557 +++++++------ _wrapper/src/refprop_wrapper.cpp | 32 +- package.mo | 29 +- request | 1 - status | 1 - 19 files changed, 336 insertions(+), 1584 deletions(-) delete mode 100644 Examples.mo delete mode 100644 Media/NH3_Water.mo delete mode 100644 Media/Pentane.mo delete mode 100644 Media/R410mix.mo delete mode 100644 Media/Water.mo delete mode 100644 Testers/Water_MixtureTwoPhase_pT.mo delete mode 100644 _wrapper/bin/refprop_library.h rename _wrapper/{src/refpropwrappertest.cpp => cpptest/refpropwrappertest_new.cpp} (92%) delete mode 100644 request delete mode 100644 status diff --git a/Examples.mo b/Examples.mo deleted file mode 100644 index a40086b..0000000 --- a/Examples.mo +++ /dev/null @@ -1,7 +0,0 @@ -within REFPROP2Modelica; -package Examples "Demonstration of the usage of the library" -extends Modelica.Icons.ExamplesPackage; -annotation(preferedView="info", - __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", - "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); -end Examples; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 4f849d9..2286fc7 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -69,7 +69,7 @@ partial package REFPROPMixtureTwoPhaseMedium input String errormsg; // input Integer debug=1; output Real val; - external "C" val= props_REFPROP( + external"C" val= props_REFPROP( what2calc, statevars, fluidnames, @@ -100,7 +100,6 @@ partial package REFPROPMixtureTwoPhaseMedium algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); // Modelica.Utilities.Streams.print("Calc "+what2calc); - val := getProp_REFPROP( what2calc, statevars, @@ -113,7 +112,6 @@ partial package REFPROPMixtureTwoPhaseMedium X, phase, errormsg) "just passing through"; - // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); @@ -531,36 +529,6 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_phX; - redeclare function extends setBubbleState - "set the thermodynamic state on the bubble line" - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(bubbleEnthalpy(sat)) + ",X)..."); - end if; - state := setState( - "pq", - sat.psat, - 0, - sat.X, - phase) ",fluidnames)"; - end setBubbleState; - - redeclare function extends setDewState - "set the thermodynamic state on the bubble line" - algorithm - if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(dewEnthalpy(sat)) + ",X)..."); - end if; - state := setState( - "pq", - sat.psat, - 1, - sat.X, - phase) ",fluidnames)"; - end setDewState; - function setState_pqX "Calculates medium properties from p,q,X" extends Modelica.Icons.Function; input Modelica.SIunits.AbsolutePressure p "Pressure"; @@ -686,34 +654,14 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hv := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", + hv := getProp_REFPROP_check( + "h", "pq", - fluidnames, - ders, - trns, - props, sat.psat, 1, sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hv :=props[10]; - + 1); end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" @@ -730,66 +678,26 @@ end ThermodynamicState; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; - //algorithm - // dv := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 1); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 1, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dv :=props[5]; - + dv := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 1, + sat.X, + 1); end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hl := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hl :=props[10]; - + hl := getProp_REFPROP_check( + "h", + "pq", + sat.psat, + 0, + sat.X, + 1); end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" @@ -806,35 +714,14 @@ end ThermodynamicState; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; - //algorithm - // dl := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 1); - - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dl :=props[5]; - + dl := getProp_REFPROP_check( + "d", + "pq", + sat.psat, + 0, + sat.X, + 1); end bubbleDensity; redeclare replaceable function extends molarMass diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo deleted file mode 100644 index 4ca5e00..0000000 --- a/Media/NH3_Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package NH3_Water "Ammonia and water mixture by REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"ammoniaL","water"}); -end NH3_Water; diff --git a/Media/Pentane.mo b/Media/Pentane.mo deleted file mode 100644 index 22d21a6..0000000 --- a/Media/Pentane.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Pentane "Pentane from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"pentane"}); -end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo deleted file mode 100644 index 1d03112..0000000 --- a/Media/R410mix.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package R410mix "R410 defined as mixture in REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); -end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo deleted file mode 100644 index 67db3b5..0000000 --- a/Media/Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Water "Water from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"water"}); -end Water; diff --git a/Media/package.order b/Media/package.order index 5841ec9..453f582 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,4 +1,4 @@ Pentane R410mix +R410 Water -NH3_Water diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 7a255ab..0292e7b 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; model PropsMixtureNH3H2O package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammoniaL","water"}, + final substanceNames={"ammonia","water"}, inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); Medium.ThermodynamicState state; @@ -13,14 +13,6 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; - Medium.SaturationProperties sat = Medium.setSat_pX(p,X); - - Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); - Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); - - Medium.Density dl = Medium.bubbleDensity(sat); - Medium.Density dv = Medium.dewDensity(sat); - protected Modelica.SIunits.Temperature T_init = 400; Real[2] X_init = {0.5,0.5}; @@ -33,8 +25,6 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); - p = Medium.pressure(state); q = Medium.vapourQuality(state); - end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index a13a30c..7b79646 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -8,19 +8,8 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Real q = Medium.vapourQuality(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); - - Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); - Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); - Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); - Medium.Density dl = Medium.bubbleDensity(sat); - Medium.Density dv = Medium.dewDensity(sat); - - Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); - Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); - equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {.5}; - + props.Xi = {0.5}; end PropsMixtureTwo; diff --git a/Testers/PropsPureSubstance.mo b/Testers/PropsPureSubstance.mo index 94d9161..e23b4a8 100644 --- a/Testers/PropsPureSubstance.mo +++ b/Testers/PropsPureSubstance.mo @@ -5,7 +5,7 @@ model PropsPureSubstance //package Medium = REFPROPMedium(final substanceNames={"water"}, final explicitVars = "pT"); //package Medium = REFPROPMedium(final substanceNames={"ammonia"}); //package Medium = REFPROPMedium(final substanceNames={"co2"}); -package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNames={"butane"}); +package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium(final substanceNames={"butane"},debugmode=true); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"water"}); //package Medium = REFPROPMediumPureSubstance(final substanceNames={"ammonia"}, final explicitVars = "ph"); Medium.BaseProperties props; @@ -15,14 +15,14 @@ package Medium = REFPROP2Modelica.REFPROPMediumPureSubstance (final substanceNam // Modelica.SIunits.SpecificEnthalpy h; // Modelica.SIunits.SpecificEntropy s; // Modelica.SIunits.Temperature T=props.T; - Modelica.SIunits.Pressure psat=Medium.saturationPressure(300); + Modelica.SIunits.Pressure psat=Medium.saturationPressure(300,{1}); // Modelica.SIunits.MolarMass MM; Real q= Medium.vapourQuality(props.state); // Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; // Modelica.SIunits.ThermalConductivity lambda= Medium.thermalConductivity(props.state); // Modelica.SIunits.DynamicViscosity eta = Medium.dynamicViscosity(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); - Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300); + Medium.SaturationProperties sat=Medium.SaturationProperties(1e5,300,{1}); equation props.p = 1e5 "sine_p.y"; props.h = 0+time*722774; diff --git a/Testers/R410mixTester.mo b/Testers/R410mixTester.mo index 96f0283..c28c7c3 100644 --- a/Testers/R410mixTester.mo +++ b/Testers/R410mixTester.mo @@ -1,6 +1,6 @@ within REFPROP2Modelica.Testers; model R410mixTester "Density of saturated R410 vapour" -package Medium = REFPROP2Modelica.Media.R410mix; +package Medium = REFPROP2Modelica.Media.R410mix(debugmode=true); Medium.BaseProperties props; Medium.Density d; Medium.SpecificEnthalpy h(start=300e3); diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo deleted file mode 100644 index deb20fd..0000000 --- a/Testers/Water_MixtureTwoPhase_pT.mo +++ /dev/null @@ -1,286 +0,0 @@ -within REFPROP2Modelica.Testers; -package Water_MixtureTwoPhase_pT - "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( - final mediumName="TwoPhaseMixtureWater", - final substanceNames={"water"}, - final reducedX = true, - final singleState=false, - reference_X=cat(1,fill(0,nX-1),{1}), - fluidConstants = BrineConstants); -// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - redeclare model extends BaseProperties "Base properties of medium" - Real GVF=q*d/d_g "gas void fraction"; - Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ - /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); - Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ - Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); - Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); - Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) - "(min=0,max=1) gas phase mass fraction"; - // Integer phase_out "calculated phase"; - //END no gas case - equation - u = h - p/d; - MM = M_H2O; - R = Modelica.Constants.R/MM; - //End GVF - //DENSITY - // q = vapourQuality(state); - d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); - // d = d_l/(1-q*(1-d_l/d_g)); - //End DENSITY - //ENTHALPY - h = specificEnthalpy_pTX(p,T,X); - /* - if (p_H2O>p) then - h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); - else - h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); - end if; - h_gas_dissolved = 0; - Delta_h_solution = solutionEnthalpy(T) - "TODO: gilt nur bei gesättigter Lösung"; -*/ - //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); - //End ENTHALPY - s=0 "TODO"; - state = ThermodynamicState( - p=p, - T=T, - X=X, - X_l=X, - h=h, - GVF=GVF, - q=q, - s=0, - d_g=d_g, - d_l=d_l, - d=d, - phase=0) "phase_out"; - sat.psat = p "TODO"; - sat.Tsat = T "saturationTemperature(p) TODO"; - sat.X = X; - annotation (Documentation(info=""), - Documentation(revisions=" - -")); - end BaseProperties; - - redeclare function specificEnthalpy_pTX - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.Temp_K T; - input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - /* input MassFraction q "(min=0,max=1)"; - input Real y "molar fraction of gas in gas phase";*/ - // input Real[3] TP; - output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); - algorithm - // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); - annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); - end specificEnthalpy_pTX; - - redeclare function temperature_phX - "numerically inverts specificEnthalpy_liquid_pTX" - input Modelica.SIunits.Pressure p; - input Modelica.SIunits.SpecificEnthalpy h; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); - algorithm - // Modelica.Utilities.Streams.print("temperature_phX"); - annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); - end temperature_phX; - -redeclare record extends ThermodynamicState - "a selection of variables that uniquely defines the thermodynamic state" -/* AbsolutePressure p "Absolute pressure of medium"; - Temperature T(unit="K") "Temperature of medium"; - MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ - SpecificEnthalpy h "Specific enthalpy"; - SpecificEntropy s "Specific entropy"; - Density d(start=300) "density"; - Real GVF "Gas Void Fraction"; - Density d_l(start=300) "density liquid phase"; - Density d_g(start=300) "density gas phase"; - Real q "vapor quality on a mass basis [mass vapor/total mass]"; - annotation (Documentation(info=" - -")); -end ThermodynamicState; - - redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" - algorithm - hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); - end dewEnthalpy; - - redeclare function extends bubbleEnthalpy - "boiling curve specific enthalpy of water" - algorithm - hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); - end bubbleEnthalpy; - - redeclare function extends saturationTemperature - algorithm - //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); - T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); - end saturationTemperature; - - redeclare function extends dynamicViscosity - algorithm - eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); - end dynamicViscosity; - -redeclare function extends specificEntropy "specific entropy of water" -algorithm - s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); -end specificEntropy; - -redeclare function specificEnthalpy_ps - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy s "Specific entropy"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy h "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEnthalpy_ps; - -redeclare function extends setState_psX - "Return thermodynamic state of water as function of p and s" -algorithm - state := ThermodynamicState( - d=density_ps(p,s), - T=temperature_ps(p,s), - phase=0, - h=specificEnthalpy_ps(p,s), - p=p, - X=X, - s=s, - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_psX; - - redeclare function extends temperature "return temperature of ideal gas" - algorithm - T := state.T; - end temperature; - - redeclare function extends density "return density of ideal gas" - algorithm - d := state.d; - end density; - -redeclare function extends setState_pTX - "Return thermodynamic state of water as function of p and T" -algorithm - state := ThermodynamicState( - d=density_pT(p,T), - T=T, - phase=0, - h=specificEnthalpy_pTX(p,s), - p=p, - X=X, - s=specificEntropy_pT(p.T), - q=-1, - GVF=-1, - d_l=-1, - d_g=-1); -end setState_pTX; - -redeclare function specificEntropy_pTX - "Computes specific enthalpy as a function of pressure and temperature" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEntropy T "Specific entropy"; - input MassFraction X[:] "mass fraction m_XCl/m_Sol"; - input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; - output SpecificEnthalpy s "specific enthalpy"; -algorithm - h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); -end specificEntropy_pTX; - - redeclare function extends thermalConductivity - "Thermal conductivity of water" - algorithm - lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( - state.d, - state.T, - state.p, - state.phase); - end thermalConductivity; - - redeclare function extends specificHeatCapacityCp - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); - else - cp := Modelica.Media.Water.IF97_Utilities.cp_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCp; - - redeclare function extends saturationPressure - algorithm - p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); - end saturationPressure; - - redeclare function extends specificHeatCapacityCv - "specific heat capacity at constant pressure of water" - algorithm - if Modelica.Media.Water.WaterIF97_base.dT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_dT( - state.d, - state.T, - state.phase); - elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then - cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); - else - cv := Modelica.Media.Water.IF97_Utilities.cv_ph( - state.p, - state.h, - state.phase); - end if; - annotation (Documentation(info=" -

In the two phase region this function returns the interpolated heat capacity between the - liquid and vapour state heat capacities.

- ")); - end specificHeatCapacityCv; - - annotation (Documentation(info=" -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index cbda809..1b48ebf 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,5 +3,4 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester -Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/bin/refprop_library.h b/_wrapper/bin/refprop_library.h deleted file mode 100644 index 5231ae8..0000000 --- a/_wrapper/bin/refprop_library.h +++ /dev/null @@ -1,788 +0,0 @@ - -#ifndef REFPROP_LIB_H -#define REFPROP_LIB_H - -/* -// The idea here is to have a common header for Windows -// and gcc-like systems. The Windows branch should cover the -// functions provided by the .dll and the gcc part covers -// the compiled .so/.dym file. Name changes caused by gfortran -// are respected and should be accounted for. -*/ -#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) -# define __ISWINDOWS__ -# include -# define _CRT_SECURE_NO_WARNINGS -#elif __APPLE__ -# define __ISAPPLE__ -#elif __linux -# define __ISLINUX__ -#endif - -// Do some manual changes to the function names -// if needed, uses CoolProp platform detection. -#if defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV __stdcall -// Do not redefine function names for the shared library, -// in this case it is the REFPROP.dll and no special -// names are needed. Macros still need a value for the -// name function used below. -# define RPVersion RPVersion -# define SETPATHdll SETPATHdll -# define ABFL1dll ABFL1dll -# define ABFL2dll ABFL2dll -# define ACTVYdll ACTVYdll -# define AGdll AGdll -# define CCRITdll CCRITdll -# define CP0dll CP0dll -# define CRITPdll CRITPdll -# define CSATKdll CSATKdll -# define CV2PKdll CV2PKdll -# define CVCPKdll CVCPKdll -# define CVCPdll CVCPdll -# define DBDTdll DBDTdll -# define DBFL1dll DBFL1dll -# define DBFL2dll DBFL2dll -# define DDDPdll DDDPdll -# define DDDTdll DDDTdll -# define DEFLSHdll DEFLSHdll -# define DHD1dll DHD1dll -# define DHFL1dll DHFL1dll -# define DHFL2dll DHFL2dll -# define DHFLSHdll DHFLSHdll -# define DIELECdll DIELECdll -# define DOTFILLdll DOTFILLdll -# define DPDD2dll DPDD2dll -# define DPDDKdll DPDDKdll -# define DPDDdll DPDDdll -# define DPDTKdll DPDTKdll -# define DPDTdll DPDTdll -# define DPTSATKdll DPTSATKdll -# define DSFLSHdll DSFLSHdll -# define DSFL1dll DSFL1dll -# define DSFL2dll DSFL2dll -# define ENTHALdll ENTHALdll -# define ENTROdll ENTROdll -# define ESFLSHdll ESFLSHdll -# define FGCTYdll FGCTYdll -# define FPVdll FPVdll -# define GERG04dll GERG04dll -# define GETFIJdll GETFIJdll -# define GETKTVdll GETKTVdll -# define GIBBSdll GIBBSdll -# define HSFLSHdll HSFLSHdll -# define INFOdll INFOdll -# define LIMITKdll LIMITKdll -# define LIMITSdll LIMITSdll -# define LIMITXdll LIMITXdll -# define MELTPdll MELTPdll -# define MELTTdll MELTTdll -# define MLTH2Odll MLTH2Odll -# define NAMEdll NAMEdll -# define PDFL1dll PDFL1dll -# define PDFLSHdll PDFLSHdll -# define PEFLSHdll PEFLSHdll -# define PHFL1dll PHFL1dll -# define PHFLSHdll PHFLSHdll -# define PQFLSHdll PQFLSHdll -# define PREOSdll PREOSdll -# define PRESSdll PRESSdll -# define PSFL1dll PSFL1dll -# define PSFLSHdll PSFLSHdll -# define PUREFLDdll PUREFLDdll -# define QMASSdll QMASSdll -# define QMOLEdll QMOLEdll -# define RESIDUALdll RESIDUALdll -# define SATDdll SATDdll -# define SATEdll SATEdll -# define SATHdll SATHdll -# define SATPdll SATPdll -# define SATSdll SATSdll -# define SATTdll SATTdll -# define SETAGAdll SETAGAdll -# define SETKTVdll SETKTVdll -# define SETMIXdll SETMIXdll -# define SETMODdll SETMODdll -# define SETREFdll SETREFdll -# define SETUPdll SETUPdll -//# define SPECGRdll SPECGRdll // not found in library -# define SUBLPdll SUBLPdll -# define SUBLTdll SUBLTdll -# define SURFTdll SURFTdll -# define SURTENdll SURTENdll -# define TDFLSHdll TDFLSHdll -# define TEFLSHdll TEFLSHdll -# define THERM0dll THERM0dll -# define THERM2dll THERM2dll -# define THERM3dll THERM3dll -# define THERMdll THERMdll -# define THFLSHdll THFLSHdll -# define TPFLSHdll TPFLSHdll -# define TPFL2dll TPFL2dll -# define TPRHOdll TPRHOdll -# define TQFLSHdll TQFLSHdll -# define TRNPRPdll TRNPRPdll -# define TSFLSHdll TSFLSHdll -# define VIRBdll VIRBdll -# define VIRCdll VIRCdll -# define WMOLdll WMOLdll -# define XMASSdll XMASSdll -# define XMOLEdll XMOLEdll -#elif defined(__ISLINUX__) // defined(__ISWINDOWS__) -// Define compiler specific calling conventions -// for the shared library. -# define CALLCONV -// Define function names for the shared library, -// in this case it is the librefprop.so and the -// names might change on some systems during -// the compilation of the Fortran files. -// Possible other branches for this code could be: -// # if !defined(_AIX) -// # if !defined(__hpux) -// # if defined( _CRAY -// However, I cannot test that and therefore do not include it. -# define RPVersion rpversion_ -# define SETPATHdll setpathdll_ -# define ABFL1dll abfl1dll_ -# define ABFL2dll abfl2dll_ -# define ACTVYdll actvydll_ -# define AGdll agdll_ -# define CCRITdll ccritdll_ -# define CP0dll cp0dll_ -# define CRITPdll critpdll_ -# define CSATKdll csatkdll_ -# define CV2PKdll cv2pkdll_ -# define CVCPKdll cvcpkdll_ -# define CVCPdll cvcpdll_ -# define DBDTdll dbdtdll_ -# define DBFL1dll dbfl1dll_ -# define DBFL2dll dbfl2dll_ -# define DDDPdll dddpdll_ -# define DDDTdll dddtdll_ -# define DEFLSHdll deflshdll_ -# define DHD1dll dhd1dll_ -# define DHFL1dll dhfl1dll_ -# define DHFL2dll dhfl2dll_ -# define DHFLSHdll dhflshdll_ -# define DIELECdll dielecdll_ -# define DOTFILLdll dotfilldll_ -# define DPDD2dll dpdd2dll_ -# define DPDDKdll dpddkdll_ -# define DPDDdll dpdddll_ -# define DPDTKdll dpdtkdll_ -# define DPDTdll dpdtdll_ -# define DPTSATKdll dptsatkdll_ -# define DSFLSHdll dsflshdll_ -# define DSFL1dll dsfl1dll_ -# define DSFL2dll dsfl2dll_ -# define ENTHALdll enthaldll_ -# define ENTROdll entrodll_ -# define ESFLSHdll esflshdll_ -# define FGCTYdll fgctydll_ -# define FPVdll fpvdll_ -# define GERG04dll gerg04dll_ -# define GETFIJdll getfijdll_ -# define GETKTVdll getktvdll_ -# define GIBBSdll gibbsdll_ -# define HSFLSHdll hsflshdll_ -# define INFOdll infodll_ -# define LIMITKdll limitkdll_ -# define LIMITSdll limitsdll_ -# define LIMITXdll limitxdll_ -# define MELTPdll meltpdll_ -# define MELTTdll melttdll_ -# define MLTH2Odll mlth2odll_ -# define NAMEdll namedll_ -# define PDFL1dll pdfl1dll_ -# define PDFLSHdll pdflshdll_ -# define PEFLSHdll peflshdll_ -# define PHFL1dll phfl1dll_ -# define PHFLSHdll phflshdll_ -# define PQFLSHdll pqflshdll_ -# define PREOSdll preosdll_ -# define PRESSdll pressdll_ -# define PSFL1dll psfl1dll_ -# define PSFLSHdll psflshdll_ -# define PUREFLDdll pureflddll_ -# define QMASSdll qmassdll_ -# define QMOLEdll qmoledll_ -# define RESIDUALdll residualdll_ -# define SATDdll satddll_ -# define SATEdll satedll_ -# define SATHdll sathdll_ -# define SATPdll satpdll_ -# define SATSdll satsdll_ -# define SATTdll sattdll_ -# define SETAGAdll setagadll_ -# define SETKTVdll setktvdll_ -# define SETMIXdll setmixdll_ -# define SETMODdll setmoddll_ -# define SETREFdll setrefdll_ -# define SETUPdll setupdll_ -//# define SPECGRdll specgrdll_ // not found in library -# define SUBLPdll sublpdll_ -# define SUBLTdll subltdll_ -# define SURFTdll surftdll_ -# define SURTENdll surtendll_ -# define TDFLSHdll tdflshdll_ -# define TEFLSHdll teflshdll_ -# define THERM0dll therm0dll_ -# define THERM2dll therm2dll_ -# define THERM3dll therm3dll_ -# define THERMdll thermdll_ -# define THFLSHdll thflshdll_ -# define TPFLSHdll tpflshdll_ -# define TPFL2dll tpfl2dll_ -# define TPRHOdll tprhodll_ -# define TQFLSHdll tqflshdll_ -# define TRNPRPdll trnprpdll_ -# define TSFLSHdll tsflshdll_ -# define VIRBdll virbdll_ -# define VIRCdll vircdll_ -# define WMOLdll wmoldll_ -# define XMASSdll xmassdll_ -# define XMOLEdll xmoledll_ -#else // #elif defined(__ISLINUX__) -// Set some dummy names for the compiler -# define CALLCONV -# define RPVersion NOTAVAILABLE -# define SETPATHdll setpathdll -# define ABFL1dll abfl1dll -# define ABFL2dll abfl2dll -# define ACTVYdll actvydll -# define AGdll agdll -# define CCRITdll ccritdll -# define CP0dll cp0dll -# define CRITPdll critpdll -# define CSATKdll csatkdll -# define CV2PKdll cv2pkdll -# define CVCPKdll cvcpkdll -# define CVCPdll cvcpdll -# define DBDTdll dbdtdll -# define DBFL1dll dbfl1dll -# define DBFL2dll dbfl2dll -# define DDDPdll dddpdll -# define DDDTdll dddtdll -# define DEFLSHdll deflshdll -# define DHD1dll dhd1dll -# define DHFL1dll dhfl1dll -# define DHFL2dll dhfl2dll -# define DHFLSHdll dhflshdll -# define DIELECdll dielecdll -# define DOTFILLdll dotfilldll -# define DPDD2dll dpdd2dll -# define DPDDKdll dpddkdll -# define DPDDdll dpdddll -# define DPDTKdll dpdtkdll -# define DPDTdll dpdtdll -# define DPTSATKdll dptsatkdll -# define DSFLSHdll dsflshdll -# define DSFL1dll dsfl1dll -# define DSFL2dll dsfl2dll -# define ENTHALdll enthaldll -# define ENTROdll entrodll -# define ESFLSHdll esflshdll -# define FGCTYdll fgctydll -# define FPVdll fpvdll -# define GERG04dll gerg04dll -# define GETFIJdll getfijdll -# define GETKTVdll getktvdll -# define GIBBSdll gibbsdll -# define HSFLSHdll hsflshdll -# define INFOdll infodll -# define LIMITKdll limitkdll -# define LIMITSdll limitsdll -# define LIMITXdll limitxdll -# define MELTPdll meltpdll -# define MELTTdll melttdll -# define MLTH2Odll mlth2odll -# define NAMEdll namedll -# define PDFL1dll pdfl1dll -# define PDFLSHdll pdflshdll -# define PEFLSHdll peflshdll -# define PHFL1dll phfl1dll -# define PHFLSHdll phflshdll -# define PQFLSHdll pqflshdll -# define PREOSdll preosdll -# define PRESSdll pressdll -# define PSFL1dll psfl1dll -# define PSFLSHdll psflshdll -# define PUREFLDdll pureflddll -# define QMASSdll qmassdll -# define QMOLEdll qmoledll -# define RESIDUALdll residualdll -# define SATDdll satddll -# define SATEdll satedll -# define SATHdll sathdll -# define SATPdll satpdll -# define SATSdll satsdll -# define SATTdll sattdll -# define SETAGAdll setagadll -# define SETKTVdll setktvdll -# define SETMIXdll setmixdll -# define SETMODdll setmoddll -# define SETREFdll setrefdll -# define SETUPdll setupdll -//# define SPECGRdll specgrdll // not found in library -# define SUBLPdll sublpdll -# define SUBLTdll subltdll -# define SURFTdll surftdll -# define SURTENdll surtendll -# define TDFLSHdll tdflshdll -# define TEFLSHdll teflshdll -# define THERM0dll therm0dll -# define THERM2dll therm2dll -# define THERM3dll therm3dll -# define THERMdll thermdll -# define THFLSHdll thflshdll -# define TPFLSHdll tpflshdll -# define TPFL2dll tpfl2dll -# define TPRHOdll tprhodll -# define TQFLSHdll tqflshdll -# define TRNPRPdll trnprpdll -# define TSFLSHdll tsflshdll -# define VIRBdll virbdll -# define VIRCdll vircdll -# define WMOLdll wmoldll -# define XMASSdll xmassdll -# define XMOLEdll xmoledll -#endif // else branch -// -// -// Only continue if function names have been defined. -// We might want to include some more tests here... -#if defined(RPVersion) -// define new macros for function names -// http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-a-c-macros-value -#include -#include -#define STR_VALUE(arg) #arg -#define FUNCTION_NAME(name) STR_VALUE(name) -// -// Prepare the strings to be used by the functions that -// handle the library later on. -#define RPVersion_NAME FUNCTION_NAME(RPVersion) -#define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) -#define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) -#define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) -#define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) -#define AGdll_NAME FUNCTION_NAME(AGdll) -#define CCRITdll_NAME FUNCTION_NAME(CCRITdll) -#define CP0dll_NAME FUNCTION_NAME(CP0dll) -#define CRITPdll_NAME FUNCTION_NAME(CRITPdll) -#define CSATKdll_NAME FUNCTION_NAME(CSATKdll) -#define CV2PKdll_NAME FUNCTION_NAME(CV2PKdll) -#define CVCPKdll_NAME FUNCTION_NAME(CVCPKdll) -#define CVCPdll_NAME FUNCTION_NAME(CVCPdll) -#define DBDTdll_NAME FUNCTION_NAME(DBDTdll) -#define DBFL1dll_NAME FUNCTION_NAME(DBFL1dll) -#define DBFL2dll_NAME FUNCTION_NAME(DBFL2dll) -#define DDDPdll_NAME FUNCTION_NAME(DDDPdll) -#define DDDTdll_NAME FUNCTION_NAME(DDDTdll) -#define DEFLSHdll_NAME FUNCTION_NAME(DEFLSHdll) -#define DHD1dll_NAME FUNCTION_NAME(DHD1dll) -#define DHFL1dll_NAME FUNCTION_NAME(DHFL1dll) -#define DHFL2dll_NAME FUNCTION_NAME(DHFL2dll) -#define DHFLSHdll_NAME FUNCTION_NAME(DHFLSHdll) -#define DIELECdll_NAME FUNCTION_NAME(DIELECdll) -#define DOTFILLdll_NAME FUNCTION_NAME(DOTFILLdll) -#define DPDD2dll_NAME FUNCTION_NAME(DPDD2dll) -#define DPDDKdll_NAME FUNCTION_NAME(DPDDKdll) -#define DPDDdll_NAME FUNCTION_NAME(DPDDdll) -#define DPDTKdll_NAME FUNCTION_NAME(DPDTKdll) -#define DPDTdll_NAME FUNCTION_NAME(DPDTdll) -#define DPTSATKdll_NAME FUNCTION_NAME(DPTSATKdll) -#define DSFLSHdll_NAME FUNCTION_NAME(DSFLSHdll) -#define DSFL1dll_NAME FUNCTION_NAME(DSFL1dll) -#define DSFL2dll_NAME FUNCTION_NAME(DSFL2dll) -#define ENTHALdll_NAME FUNCTION_NAME(ENTHALdll) -#define ENTROdll_NAME FUNCTION_NAME(ENTROdll) -#define ESFLSHdll_NAME FUNCTION_NAME(ESFLSHdll) -#define FGCTYdll_NAME FUNCTION_NAME(FGCTYdll) -#define FPVdll_NAME FUNCTION_NAME(FPVdll) -#define GERG04dll_NAME FUNCTION_NAME(GERG04dll) -#define GETFIJdll_NAME FUNCTION_NAME(GETFIJdll) -#define GETKTVdll_NAME FUNCTION_NAME(GETKTVdll) -#define GIBBSdll_NAME FUNCTION_NAME(GIBBSdll) -#define HSFLSHdll_NAME FUNCTION_NAME(HSFLSHdll) -#define INFOdll_NAME FUNCTION_NAME(INFOdll) -#define LIMITKdll_NAME FUNCTION_NAME(LIMITKdll) -#define LIMITSdll_NAME FUNCTION_NAME(LIMITSdll) -#define LIMITXdll_NAME FUNCTION_NAME(LIMITXdll) -#define MELTPdll_NAME FUNCTION_NAME(MELTPdll) -#define MELTTdll_NAME FUNCTION_NAME(MELTTdll) -#define MLTH2Odll_NAME FUNCTION_NAME(MLTH2Odll) -#define NAMEdll_NAME FUNCTION_NAME(NAMEdll) -#define PDFL1dll_NAME FUNCTION_NAME(PDFL1dll) -#define PDFLSHdll_NAME FUNCTION_NAME(PDFLSHdll) -#define PEFLSHdll_NAME FUNCTION_NAME(PEFLSHdll) -#define PHFL1dll_NAME FUNCTION_NAME(PHFL1dll) -#define PHFLSHdll_NAME FUNCTION_NAME(PHFLSHdll) -#define PQFLSHdll_NAME FUNCTION_NAME(PQFLSHdll) -#define PREOSdll_NAME FUNCTION_NAME(PREOSdll) -#define PRESSdll_NAME FUNCTION_NAME(PRESSdll) -#define PSFL1dll_NAME FUNCTION_NAME(PSFL1dll) -#define PSFLSHdll_NAME FUNCTION_NAME(PSFLSHdll) -#define PUREFLDdll_NAME FUNCTION_NAME(PUREFLDdll) -#define QMASSdll_NAME FUNCTION_NAME(QMASSdll) -#define QMOLEdll_NAME FUNCTION_NAME(QMOLEdll) -#define RESIDUALdll_NAME FUNCTION_NAME(RESIDUALdll) -#define SATDdll_NAME FUNCTION_NAME(SATDdll) -#define SATEdll_NAME FUNCTION_NAME(SATEdll) -#define SATHdll_NAME FUNCTION_NAME(SATHdll) -#define SATPdll_NAME FUNCTION_NAME(SATPdll) -#define SATSdll_NAME FUNCTION_NAME(SATSdll) -#define SATTdll_NAME FUNCTION_NAME(SATTdll) -#define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) -#define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) -#define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) -#define SETMODdll_NAME FUNCTION_NAME(SETMODdll) -#define SETREFdll_NAME FUNCTION_NAME(SETREFdll) -#define SETUPdll_NAME FUNCTION_NAME(SETUPdll) -//#define SPECGRdll_NAME FUNCTION_NAME(SPECGRdll) // not found in library -#define SUBLPdll_NAME FUNCTION_NAME(SUBLPdll) -#define SUBLTdll_NAME FUNCTION_NAME(SUBLTdll) -#define SURFTdll_NAME FUNCTION_NAME(SURFTdll) -#define SURTENdll_NAME FUNCTION_NAME(SURTENdll) -#define TDFLSHdll_NAME FUNCTION_NAME(TDFLSHdll) -#define TEFLSHdll_NAME FUNCTION_NAME(TEFLSHdll) -#define THERM0dll_NAME FUNCTION_NAME(THERM0dll) -#define THERM2dll_NAME FUNCTION_NAME(THERM2dll) -#define THERM3dll_NAME FUNCTION_NAME(THERM3dll) -#define THERMdll_NAME FUNCTION_NAME(THERMdll) -#define THFLSHdll_NAME FUNCTION_NAME(THFLSHdll) -#define TPFLSHdll_NAME FUNCTION_NAME(TPFLSHdll) -#define TPFL2dll_NAME FUNCTION_NAME(TPFL2dll) -#define TPRHOdll_NAME FUNCTION_NAME(TPRHOdll) -#define TQFLSHdll_NAME FUNCTION_NAME(TQFLSHdll) -#define TRNPRPdll_NAME FUNCTION_NAME(TRNPRPdll) -#define TSFLSHdll_NAME FUNCTION_NAME(TSFLSHdll) -#define VIRBdll_NAME FUNCTION_NAME(VIRBdll) -#define VIRCdll_NAME FUNCTION_NAME(VIRCdll) -#define WMOLdll_NAME FUNCTION_NAME(WMOLdll) -#define XMASSdll_NAME FUNCTION_NAME(XMASSdll) -#define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) -// -// I'll try to follow this example from: -// http://www.gershnik.com/tips/cpp.asp -// function type: typedef void [compiler stuff] func_t(int, float); -// function declaration: func_t func; -// pointer type: typedef func_t * func_ptr; -#if defined(__cplusplus) -extern "C" { -#endif - typedef void (CALLCONV RPVersion_TYPE)( char* ); - typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); - // - typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ACTVYdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV AGdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV CCRITdll_TYPE)(double &,double &,double &,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CP0dll_TYPE)(double &,double *,double &); - typedef void (CALLCONV CRITPdll_TYPE)(double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CV2PKdll_TYPE)(long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV CVCPKdll_TYPE)(long &,double &,double &,double &,double &); - typedef void (CALLCONV CVCPdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV DBDTdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV DBFL1dll_TYPE)(double &,double &,double *,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DBFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DDDPdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DDDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DHD1dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV DHFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV DHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DIELECdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DOTFILLdll_TYPE)(long &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV DPDD2dll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDDKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDDdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPDTKdll_TYPE)(long &,double &,double &,double &); - typedef void (CALLCONV DPDTdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV DPTSATKdll_TYPE)(long &,double &,long &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV DSFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV DSFL2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV ENTHALdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ENTROdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV ESFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV FGCTYdll_TYPE)(double &,double &,double *,double *); - typedef void (CALLCONV FPVdll_TYPE)(double &,double &,double &,double *,double &); - typedef void (CALLCONV GERG04dll_TYPE)(long &,long &,long &,char*,long ); - typedef void (CALLCONV GETFIJdll_TYPE)(char*,double *,char*,char*,long ,long ,long ); - typedef void (CALLCONV GETKTVdll_TYPE)(long &,long &,char*,double *,char*,char*,char*,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV GIBBSdll_TYPE)(double &,double &,double *,double &,double &); - typedef void (CALLCONV HSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV INFOdll_TYPE)(long &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV LIMITKdll_TYPE)(char*,long &,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV LIMITSdll_TYPE)(char*,double *,double &,double &,double &,double &,long ); - typedef void (CALLCONV LIMITXdll_TYPE)(char*,double &,double &,double &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV MELTPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MELTTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV MLTH2Odll_TYPE)(double &,double &,double &); - typedef void (CALLCONV NAMEdll_TYPE)(long &,char*,char*,char*,long ,long ,long ); - typedef void (CALLCONV PDFL1dll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV PDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PEFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PHFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PREOSdll_TYPE)(long &); - typedef void (CALLCONV PRESSdll_TYPE)(double &,double &,double *,double &); - typedef void (CALLCONV PSFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PSFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV PUREFLDdll_TYPE)(long &); - typedef void (CALLCONV QMASSdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV QMOLEdll_TYPE)(double &,double *,double *,double &,double *,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV RESIDUALdll_TYPE)(double &,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *); - typedef void (CALLCONV SATDdll_TYPE)(double &,double *,long &,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATEdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATHdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATPdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SATSdll_TYPE)(double &,double *,long &,long &,long &,double &,double &,double &,long &,double &,double &,double &,long &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV SATTdll_TYPE)(double &,double *,long &,double &,double &,double &,double *,double *,long &,char*,long ); - typedef void (CALLCONV SETAGAdll_TYPE)(long &,char*,long ); - typedef void (CALLCONV SETKTVdll_TYPE)(long &,long &,char*,double *,char*,long &,char*,long ,long ,long ); - typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long &,char*,double *,long &,char*,long ,long ,long ,long ,long ); - typedef void (CALLCONV SETMODdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SETREFdll_TYPE)(char*,long &,double *,double &,double &,double &,double &,long &,char*,long ,long ); - typedef void (CALLCONV SETUPdll_TYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); - typedef void (CALLCONV SPECGRdll_TYPE)(double &,double &,double &,double &); - typedef void (CALLCONV SUBLPdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SUBLTdll_TYPE)(double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURFTdll_TYPE)(double &,double &,double *,double &,long &,char*,long ); - typedef void (CALLCONV SURTENdll_TYPE)(double &,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TDFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TEFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV THERM0dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM2dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERM3dll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THERMdll_TYPE)(double &,double &,double *,double &,double &,double &,double &,double &,double &,double &,double &); - typedef void (CALLCONV THFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFLSHdll_TYPE)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TPFL2dll_TYPE)(double &,double &,double *,double &,double &,double *,double *,double &,long &,char*,long ); - typedef void (CALLCONV TPRHOdll_TYPE)(double &,double &,double *,long &,long &,double &,long &,char*,long ); - typedef void (CALLCONV TQFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV TRNPRPdll_TYPE)(double &,double &,double *,double &,double &,long &,char*,long ); - typedef void (CALLCONV TSFLSHdll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); - typedef void (CALLCONV VIRBdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV VIRCdll_TYPE)(double &,double *,double &); - typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); - typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); - typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); -// -// Disabled because we prefer pointers here! -// // Declare the functions for direct access, -// RPVersion_TYPE RPVersion; -// SETPATHdll_TYPE SETPATHdll; -// ABFL1dll_TYPE ABFL1dll; -// ABFL2dll_TYPE ABFL2dll; -// ACTVYdll_TYPE ACTVYdll; -// AGdll_TYPE AGdll; -// CCRITdll_TYPE CCRITdll; -// CP0dll_TYPE CP0dll; -// CRITPdll_TYPE CRITPdll; -// CSATKdll_TYPE CSATKdll; -// CV2PKdll_TYPE CV2PKdll; -// CVCPKdll_TYPE CVCPKdll; -// CVCPdll_TYPE CVCPdll; -// DBDTdll_TYPE DBDTdll; -// DBFL1dll_TYPE DBFL1dll; -// DBFL2dll_TYPE DBFL2dll; -// DDDPdll_TYPE DDDPdll; -// DDDTdll_TYPE DDDTdll; -// DEFLSHdll_TYPE DEFLSHdll; -// DHD1dll_TYPE DHD1dll; -// DHFLSHdll_TYPE DHFLSHdll; -// DHFL1dll_TYPE DHFL1dll; -// DHFL2dll_TYPE DHFL2dll; -// DIELECdll_TYPE DIELECdll; -// DOTFILLdll_TYPE DOTFILLdll; -// DPDD2dll_TYPE DPDD2dll; -// DPDDKdll_TYPE DPDDKdll; -// DPDDdll_TYPE DPDDdll; -// DPDTKdll_TYPE DPDTKdll; -// DPDTdll_TYPE DPDTdll; -// DPTSATKdll_TYPE DPTSATKdll; -// DSFLSHdll_TYPE DSFLSHdll; -// DSFL1dll_TYPE DSFL1dll; -// DSFL2dll_TYPE DSFL2dll; -// ENTHALdll_TYPE ENTHALdll; -// ENTROdll_TYPE ENTROdll; -// ESFLSHdll_TYPE ESFLSHdll; -// FGCTYdll_TYPE FGCTYdll; -// FPVdll_TYPE FPVdll; -// GERG04dll_TYPE GERG04dll; -// GETFIJdll_TYPE GETFIJdll; -// GETKTVdll_TYPE GETKTVdll; -// GIBBSdll_TYPE GIBBSdll; -// HSFLSHdll_TYPE HSFLSHdll; -// INFOdll_TYPE INFOdll; -// LIMITKdll_TYPE LIMITKdll; -// LIMITSdll_TYPE LIMITSdll; -// LIMITXdll_TYPE LIMITXdll; -// MELTPdll_TYPE MELTPdll; -// MELTTdll_TYPE MELTTdll; -// MLTH2Odll_TYPE MLTH2Odll; -// NAMEdll_TYPE NAMEdll; -// PDFL1dll_TYPE PDFL1dll; -// PDFLSHdll_TYPE PDFLSHdll; -// PEFLSHdll_TYPE PEFLSHdll; -// PHFL1dll_TYPE PHFL1dll; -// PHFLSHdll_TYPE PHFLSHdll; -// PQFLSHdll_TYPE PQFLSHdll; -// PREOSdll_TYPE PREOSdll; -// PRESSdll_TYPE PRESSdll; -// PSFL1dll_TYPE PSFL1dll; -// PSFLSHdll_TYPE PSFLSHdll; -// PUREFLDdll_TYPE PUREFLDdll; -// QMASSdll_TYPE QMASSdll; -// QMOLEdll_TYPE QMOLEdll; -// SATDdll_TYPE SATDdll; -// SATEdll_TYPE SATEdll; -// SATHdll_TYPE SATHdll; -// SATPdll_TYPE SATPdll; -// SATSdll_TYPE SATSdll; -// SATTdll_TYPE SATTdll; -// SETAGAdll_TYPE SETAGAdll; -// SETKTVdll_TYPE SETKTVdll; -// SETMIXdll_TYPE SETMIXdll; -// SETMODdll_TYPE SETMODdll; -// SETREFdll_TYPE SETREFdll; -// SETUPdll_TYPE SETUPdll; -//// SPECGRdll_TYPE SPECGRdll; // not found in library -// SUBLPdll_TYPE SUBLPdll; -// SUBLTdll_TYPE SUBLTdll; -// SURFTdll_TYPE SURFTdll; -// SURTENdll_TYPE SURTENdll; -// TDFLSHdll_TYPE TDFLSHdll; -// TEFLSHdll_TYPE TEFLSHdll; -// THERM0dll_TYPE THERM0dll; -// THERM2dll_TYPE THERM2dll; -// THERM3dll_TYPE THERM3dll; -// THERMdll_TYPE THERMdll; -// THFLSHdll_TYPE THFLSHdll; -// TPFLSHdll_TYPE TPFLSHdll; -// TPFL2dll_TYPE TPFL2dll; -// TPRHOdll_TYPE TPRHOdll; -// TQFLSHdll_TYPE TQFLSHdll; -// TRNPRPdll_TYPE TRNPRPdll; -// TSFLSHdll_TYPE TSFLSHdll; -// VIRBdll_TYPE VIRBdll; -// VIRCdll_TYPE VIRCdll; -// WMOLdll_TYPE WMOLdll; -// XMASSdll_TYPE XMASSdll; -// XMOLEdll_TYPE XMOLEdll; - // - // Define explicit function pointers - typedef RPVersion_TYPE * RPVersion_POINTER; - typedef SETPATHdll_TYPE * SETPATHdll_POINTER; - typedef ABFL1dll_TYPE * ABFL1dll_POINTER; - typedef ABFL2dll_TYPE * ABFL2dll_POINTER; - typedef ACTVYdll_TYPE * ACTVYdll_POINTER; - typedef AGdll_TYPE * AGdll_POINTER; - typedef CCRITdll_TYPE * CCRITdll_POINTER; - typedef CP0dll_TYPE * CP0dll_POINTER; - typedef CRITPdll_TYPE * CRITPdll_POINTER; - typedef CSATKdll_TYPE * CSATKdll_POINTER; - typedef CV2PKdll_TYPE * CV2PKdll_POINTER; - typedef CVCPKdll_TYPE * CVCPKdll_POINTER; - typedef CVCPdll_TYPE * CVCPdll_POINTER; - typedef DBDTdll_TYPE * DBDTdll_POINTER; - typedef DBFL1dll_TYPE * DBFL1dll_POINTER; - typedef DBFL2dll_TYPE * DBFL2dll_POINTER; - typedef DDDPdll_TYPE * DDDPdll_POINTER; - typedef DDDTdll_TYPE * DDDTdll_POINTER; - typedef DEFLSHdll_TYPE * DEFLSHdll_POINTER; - typedef DHD1dll_TYPE * DHD1dll_POINTER; - typedef DHFLSHdll_TYPE * DHFLSHdll_POINTER; - typedef DHFL1dll_TYPE * DHFL1dll_POINTER; - typedef DHFL2dll_TYPE * DHFL2dll_POINTER; - typedef DIELECdll_TYPE * DIELECdll_POINTER; - typedef DOTFILLdll_TYPE * DOTFILLdll_POINTER; - typedef DPDD2dll_TYPE * DPDD2dll_POINTER; - typedef DPDDKdll_TYPE * DPDDKdll_POINTER; - typedef DPDDdll_TYPE * DPDDdll_POINTER; - typedef DPDTKdll_TYPE * DPDTKdll_POINTER; - typedef DPDTdll_TYPE * DPDTdll_POINTER; - typedef DPTSATKdll_TYPE * DPTSATKdll_POINTER; - typedef DSFLSHdll_TYPE * DSFLSHdll_POINTER; - typedef DSFL1dll_TYPE * DSFL1dll_POINTER; - typedef DSFL2dll_TYPE * DSFL2dll_POINTER; - typedef ENTHALdll_TYPE * ENTHALdll_POINTER; - typedef ENTROdll_TYPE * ENTROdll_POINTER; - typedef ESFLSHdll_TYPE * ESFLSHdll_POINTER; - typedef FGCTYdll_TYPE * FGCTYdll_POINTER; - typedef FPVdll_TYPE * FPVdll_POINTER; - typedef GERG04dll_TYPE * GERG04dll_POINTER; - typedef GETFIJdll_TYPE * GETFIJdll_POINTER; - typedef GETKTVdll_TYPE * GETKTVdll_POINTER; - typedef GIBBSdll_TYPE * GIBBSdll_POINTER; - typedef HSFLSHdll_TYPE * HSFLSHdll_POINTER; - typedef INFOdll_TYPE * INFOdll_POINTER; - typedef LIMITKdll_TYPE * LIMITKdll_POINTER; - typedef LIMITSdll_TYPE * LIMITSdll_POINTER; - typedef LIMITXdll_TYPE * LIMITXdll_POINTER; - typedef MELTPdll_TYPE * MELTPdll_POINTER; - typedef MELTTdll_TYPE * MELTTdll_POINTER; - typedef MLTH2Odll_TYPE * MLTH2Odll_POINTER; - typedef NAMEdll_TYPE * NAMEdll_POINTER; - typedef PDFL1dll_TYPE * PDFL1dll_POINTER; - typedef PDFLSHdll_TYPE * PDFLSHdll_POINTER; - typedef PEFLSHdll_TYPE * PEFLSHdll_POINTER; - typedef PHFL1dll_TYPE * PHFL1dll_POINTER; - typedef PHFLSHdll_TYPE * PHFLSHdll_POINTER; - typedef PQFLSHdll_TYPE * PQFLSHdll_POINTER; - typedef PREOSdll_TYPE * PREOSdll_POINTER; - typedef PRESSdll_TYPE * PRESSdll_POINTER; - typedef PSFL1dll_TYPE * PSFL1dll_POINTER; - typedef PSFLSHdll_TYPE * PSFLSHdll_POINTER; - typedef PUREFLDdll_TYPE * PUREFLDdll_POINTER; - typedef QMASSdll_TYPE * QMASSdll_POINTER; - typedef QMOLEdll_TYPE * QMOLEdll_POINTER; - typedef RESIDUALdll_TYPE * RESIDUALdll_POINTER; - typedef SATDdll_TYPE * SATDdll_POINTER; - typedef SATEdll_TYPE * SATEdll_POINTER; - typedef SATHdll_TYPE * SATHdll_POINTER; - typedef SATPdll_TYPE * SATPdll_POINTER; - typedef SATSdll_TYPE * SATSdll_POINTER; - typedef SATTdll_TYPE * SATTdll_POINTER; - typedef SETAGAdll_TYPE * SETAGAdll_POINTER; - typedef SETKTVdll_TYPE * SETKTVdll_POINTER; - typedef SETMIXdll_TYPE * SETMIXdll_POINTER; - typedef SETMODdll_TYPE * SETMODdll_POINTER; - typedef SETREFdll_TYPE * SETREFdll_POINTER; - typedef SETUPdll_TYPE * SETUPdll_POINTER; -// typedef SPECGRdll_TYPE * SPECGRdll_POINTER; // not found in library - typedef SUBLPdll_TYPE * SUBLPdll_POINTER; - typedef SUBLTdll_TYPE * SUBLTdll_POINTER; - typedef SURFTdll_TYPE * SURFTdll_POINTER; - typedef SURTENdll_TYPE * SURTENdll_POINTER; - typedef TDFLSHdll_TYPE * TDFLSHdll_POINTER; - typedef TEFLSHdll_TYPE * TEFLSHdll_POINTER; - typedef THERM0dll_TYPE * THERM0dll_POINTER; - typedef THERM2dll_TYPE * THERM2dll_POINTER; - typedef THERM3dll_TYPE * THERM3dll_POINTER; - typedef THERMdll_TYPE * THERMdll_POINTER; - typedef THFLSHdll_TYPE * THFLSHdll_POINTER; - typedef TPFLSHdll_TYPE * TPFLSHdll_POINTER; - typedef TPFL2dll_TYPE * TPFL2dll_POINTER; - typedef TPRHOdll_TYPE * TPRHOdll_POINTER; - typedef TQFLSHdll_TYPE * TQFLSHdll_POINTER; - typedef TRNPRPdll_TYPE * TRNPRPdll_POINTER; - typedef TSFLSHdll_TYPE * TSFLSHdll_POINTER; - typedef VIRBdll_TYPE * VIRBdll_POINTER; - typedef VIRCdll_TYPE * VIRCdll_POINTER; - typedef WMOLdll_TYPE * WMOLdll_POINTER; - typedef XMASSdll_TYPE * XMASSdll_POINTER; - typedef XMOLEdll_TYPE * XMOLEdll_POINTER; -#if defined(__cplusplus) -} // extern "C" -#endif // __cplusplus -#endif // defined(RPversion) -#endif // REFPROP_LIB_H diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/cpptest/refpropwrappertest_new.cpp similarity index 92% rename from _wrapper/src/refpropwrappertest.cpp rename to _wrapper/cpptest/refpropwrappertest_new.cpp index 483f5f2..f904c7b 100644 --- a/_wrapper/src/refpropwrappertest.cpp +++ b/_wrapper/cpptest/refpropwrappertest_new.cpp @@ -1,275 +1,282 @@ -#include -#include -#include -#include -#include "refprop_wrapper.h" -#include "refprop_library.h" -#include -#include - - - -//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); -//double density(char* fluidname_in, double p, double t); -//double density(double p, double t); -//char *str_replace(char *str, char *search, char *replace, long *count); - -int main(int argc, char* argv[]){ - double p,t,d; - char fluidname[255]; - char errormsg[255]; - double* x; - double *props; - double *ders; - double *trns; - double sumx; - int i; -// int nX = argc-5; - int DEBUG = 0; - - - -/* - int count; - printf ("This program was called with \"%s\".\n",argv[0]); - if (argc > 1) - { - for (count = 1; count < argc; count++) - { - printf("argv[%d] = %s\n", count, argv[count]); - } - } - else - { - printf("The command had no other arguments.\n"); - } -printf("argc is %li \n",argc); -*/ - - -/* - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); -// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); - return 1; - } -*/ -// usage -// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 - -int nX=2; - - x = (double*) calloc(nX,sizeof(double)); - props=(double*) calloc(16+2*nX,sizeof(double)); - ders=(double*) calloc(21,sizeof(double)); - trns=(double*) calloc(3,sizeof(double)); - -x[0] = 0.5; -x[1] = 1.0-x[0]; -//x[2] = 1-x[1]; - - - - - -/* - sumx = 0; - for (i=0;i +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;i components_split = strsplit(sFluids,'|');// Split into components - - //printf ("%s \n",RefString.c_str()); - RefString.clear(); // Flush out fluid string // Build new fluid string @@ -981,7 +983,7 @@ double getS_modelica() { double getWM_modelica(){ //molecular weight - return dwm/1000; // g/mol to kg/mol + return dwm/1000; } double getDL_modelica(){ @@ -1367,12 +1369,6 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = -1. * ddhdp_d / ddhdd_p; ddddh_p = 1./ddhdd_p; } else { // two-phase region, get derivative of density with respect to enthalpy numerically - - - // TODO - ddddp_h = -1; - ddddh_p = -1; - /* if (debug) printf ("Using two-phase derivatives.\n"); deltaP = 0.00005; // 0.05 Pascal difference pLow = dp - 0.5*deltaP; @@ -1400,7 +1396,6 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); - */ } } else { // We have a problem! @@ -1679,7 +1674,7 @@ OUTPUT // Set variables to input values if ( strCompare(in1, in2) ) { sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return FAIL; + return -1; } memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; @@ -1912,15 +1907,12 @@ OUTPUT updateProps(props, lerr); + //int outVal = ders_REFPROP(ders,errormsg,debug); + //if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - // TODO - /* - int outVal = ders_REFPROP(ders,errormsg,debug); - if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + //outVal = trns_REFPROP(trns,errormsg,debug); + //if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - outVal = trns_REFPROP(trns,errormsg,debug); - if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - */ if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); diff --git a/package.mo b/package.mo index 98dad2c..273e63d 100644 --- a/package.mo +++ b/package.mo @@ -1,26 +1,17 @@ within ; package REFPROP2Modelica - constant String REFPROP_PATH = "C:\\Program Files (x86)\\REFPROP"; -// constant String REFPROP_PATH = "/opt/refprop"; + constant String REFPROP_PATH = "C:\\Program Files\\REFPROP"; + // constant String REFPROP_PATH = "/opt/refprop"; - - annotation (version="0.2", uses(Modelica(version="3.2")), - Documentation(info=" -

-Documentation is found in the packages. Installation directions are found in both REFPROP packages. -

-

Contact for original implementation:

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -", - revisions=" + annotation(version = "0.2", uses(Modelica(version = "3.2")), Documentation(info=" +

Documentation is found in the packages. Installation directions are found in both REFPROP packages.

+

Contact for original implementation:

+

Henning Francke

Helmholtz Centre Potsdam

GFZ German Research Centre for Geosciences

Telegrafenberg, D-14473 Potsdam

Germany

francke@gfz-potsdam.de

+


Contact for this version:

+

Jorrit Wronski

DTU Mechanical Engineering

Technical University of Denmark

Nils Koppels Allé

Building 403 Room 111

2800 Kgs. Lyngby

Denmark

jowr@mek.dtu.dk

+", + revisions = " ")); end REFPROP2Modelica; diff --git a/request b/request deleted file mode 100644 index 8d1c8b6..0000000 --- a/request +++ /dev/null @@ -1 +0,0 @@ - diff --git a/status b/status deleted file mode 100644 index 8d1c8b6..0000000 --- a/status +++ /dev/null @@ -1 +0,0 @@ - From a5b936db3fc658a406605c20a03e627f41856c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 26 Nov 2013 09:06:04 +0100 Subject: [PATCH 41/57] Modelica: Included setBubbleState and setDewState... Wrapper: Outcommented partial derivative and transport functions for speed testing.. --- Examples.mo | 7 + Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 163 ++++++++++-- Media/NH3_Water.mo | 5 + Media/Pentane.mo | 5 + Media/R410mix.mo | 5 + Media/Water.mo | 5 + Media/package.order | 2 +- Testers/PropsMixtureNH3H2O.mo | 12 +- Testers/PropsMixtureTwo.mo | 13 +- Testers/Water_MixtureTwoPhase_pT.mo | 286 +++++++++++++++++++++ Testers/package.order | 1 + _wrapper/src/refprop_wrapper.cpp | 22 +- _wrapper/src/refpropwrappertest.cpp | 275 ++++++++++++++++++++ 13 files changed, 767 insertions(+), 34 deletions(-) create mode 100644 Examples.mo create mode 100644 Media/NH3_Water.mo create mode 100644 Media/Pentane.mo create mode 100644 Media/R410mix.mo create mode 100644 Media/Water.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT.mo create mode 100644 _wrapper/src/refpropwrappertest.cpp diff --git a/Examples.mo b/Examples.mo new file mode 100644 index 0000000..a40086b --- /dev/null +++ b/Examples.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" +extends Modelica.Icons.ExamplesPackage; +annotation(preferedView="info", + __Dymola_classOrder={"PumpingSystem", "HeatingSystem", "DrumBoiler", "Tanks", "ControlledTankSystem", "AST_BatchPlant", + "IncompressibleFluidNetwork", "BranchingDynamicPipes", "HeatExchanger", "TraceSubstances", "InverseParameterization", "Explanatory", "*"}); +end Examples; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 2286fc7..4f849d9 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -69,7 +69,7 @@ partial package REFPROPMixtureTwoPhaseMedium input String errormsg; // input Integer debug=1; output Real val; - external"C" val= props_REFPROP( + external "C" val= props_REFPROP( what2calc, statevars, fluidnames, @@ -100,6 +100,7 @@ partial package REFPROPMixtureTwoPhaseMedium algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); // Modelica.Utilities.Streams.print("Calc "+what2calc); + val := getProp_REFPROP( what2calc, statevars, @@ -112,6 +113,7 @@ partial package REFPROPMixtureTwoPhaseMedium X, phase, errormsg) "just passing through"; + // Modelica.Utilities.Streams.print("ERR("+String(props[1])+"):"+errormsg); assert(props[1] == 0, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); @@ -529,6 +531,36 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_phX; + redeclare function extends setBubbleState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(bubbleEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 0, + sat.X, + phase) ",fluidnames)"; + end setBubbleState; + + redeclare function extends setDewState + "set the thermodynamic state on the bubble line" + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + + String(dewEnthalpy(sat)) + ",X)..."); + end if; + state := setState( + "pq", + sat.psat, + 1, + sat.X, + phase) ",fluidnames)"; + end setDewState; + function setState_pqX "Calculates medium properties from p,q,X" extends Modelica.Icons.Function; input Modelica.SIunits.AbsolutePressure p "Pressure"; @@ -654,14 +686,34 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hv := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hv := getProp_REFPROP_check( - "h", + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", "pq", + fluidnames, + ders, + trns, + props, sat.psat, 1, sat.X, - 1); + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hv :=props[10]; + end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" @@ -678,26 +730,66 @@ end ThermodynamicState; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; + //algorithm + // dv := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 1, + // sat.X, + // 1); + extends partialREFPROP; + algorithm - dv := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 1, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 1, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dv :=props[5]; + end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; + //algorithm + // hl := getProp_REFPROP_check( + // "h", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 0); + extends partialREFPROP; + algorithm - hl := getProp_REFPROP_check( - "h", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + hl :=props[10]; + end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" @@ -714,14 +806,35 @@ end ThermodynamicState; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; + //algorithm + // dl := getProp_REFPROP_check( + // "d", + // "pq", + // sat.psat, + // 0, + // sat.X, + // 1); + + extends partialREFPROP; + algorithm - dl := getProp_REFPROP_check( - "d", - "pq", - sat.psat, - 0, - sat.X, - 1); + assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getProp_REFPROP( + "u", + "pq", + fluidnames, + ders, + trns, + props, + sat.psat, + 0, + sat.X, + 1, + errormsg); + assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + dl :=props[5]; + end bubbleDensity; redeclare replaceable function extends molarMass diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo new file mode 100644 index 0000000..4ca5e00 --- /dev/null +++ b/Media/NH3_Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package NH3_Water "Ammonia and water mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"ammoniaL","water"}); +end NH3_Water; diff --git a/Media/Pentane.mo b/Media/Pentane.mo new file mode 100644 index 0000000..22d21a6 --- /dev/null +++ b/Media/Pentane.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Pentane "Pentane from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"pentane"}); +end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo new file mode 100644 index 0000000..1d03112 --- /dev/null +++ b/Media/R410mix.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package R410mix "R410 defined as mixture in REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); +end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo new file mode 100644 index 0000000..67db3b5 --- /dev/null +++ b/Media/Water.mo @@ -0,0 +1,5 @@ +within REFPROP2Modelica.Media; +package Water "Water from REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"water"}); +end Water; diff --git a/Media/package.order b/Media/package.order index 453f582..5841ec9 100644 --- a/Media/package.order +++ b/Media/package.order @@ -1,4 +1,4 @@ Pentane R410mix -R410 Water +NH3_Water diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 0292e7b..7a255ab 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -1,7 +1,7 @@ within REFPROP2Modelica.Testers; model PropsMixtureNH3H2O package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammonia","water"}, + final substanceNames={"ammoniaL","water"}, inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); Medium.ThermodynamicState state; @@ -13,6 +13,14 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; + Medium.SaturationProperties sat = Medium.setSat_pX(p,X); + + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + protected Modelica.SIunits.Temperature T_init = 400; Real[2] X_init = {0.5,0.5}; @@ -25,6 +33,8 @@ equation X[2] = 1 - X[1]; T = 350 + 100 * time; state = Medium.setState_dTX(d,T,X); + p = Medium.pressure(state); q = Medium.vapourQuality(state); + end PropsMixtureNH3H2O; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index 7b79646..a13a30c 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -8,8 +8,19 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Real q = Medium.vapourQuality(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); + + Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); + Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); + Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); + Medium.Density dl = Medium.bubbleDensity(sat); + Medium.Density dv = Medium.dewDensity(sat); + + Medium.ThermodynamicState state_l=Medium.setState_pqX(props.p,0,props.X); + Medium.ThermodynamicState state_v=Medium.setState_pqX(props.p,1,props.X); + equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {0.5}; + props.Xi = {.5}; + end PropsMixtureTwo; diff --git a/Testers/Water_MixtureTwoPhase_pT.mo b/Testers/Water_MixtureTwoPhase_pT.mo new file mode 100644 index 0000000..deb20fd --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT.mo @@ -0,0 +1,286 @@ +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT + "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium( + final mediumName="TwoPhaseMixtureWater", + final substanceNames={"water"}, + final reducedX = true, + final singleState=false, + reference_X=cat(1,fill(0,nX-1),{1}), + fluidConstants = BrineConstants); +// final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + redeclare model extends BaseProperties "Base properties of medium" + Real GVF=q*d/d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l)/(h_g - h_l+ 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case + equation + u = h - p/d; + MM = M_H2O; + R = Modelica.Constants.R/MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p,h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p,T,X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei gesättigter Lösung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s=0 "TODO"; + state = ThermodynamicState( + p=p, + T=T, + X=X, + X_l=X, + h=h, + GVF=GVF, + q=q, + s=0, + d_g=d_g, + d_l=d_l, + d=d, + phase=0) "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation (Documentation(info=""), + Documentation(revisions=" + +")); + end BaseProperties; + + redeclare function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h=Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T); + algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline=true,inverse(T = temperature_phX(p=p,h=h,X=X,phase=phase))); + end specificEnthalpy_pTX; + + redeclare function temperature_phX + "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T=Modelica.Media.Water.WaterIF97_base.temperature_ph(p,h); + algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline=true,inverse(h = specificEnthalpy_pTX(p=p,T=T,phase=phase,X=X))); + end temperature_phX; + +redeclare record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" +/* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start=300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start=300) "density liquid phase"; + Density d_g(start=300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation (Documentation(info=" + +")); +end ThermodynamicState; + + redeclare function extends dewEnthalpy "dew curve specific enthalpy of water" + algorithm + hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat); + end dewEnthalpy; + + redeclare function extends bubbleEnthalpy + "boiling curve specific enthalpy of water" + algorithm + hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); + end bubbleEnthalpy; + + redeclare function extends saturationTemperature + algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T := Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); + end saturationTemperature; + + redeclare function extends dynamicViscosity + algorithm + eta := Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); + end dynamicViscosity; + +redeclare function extends specificEntropy "specific entropy of water" +algorithm + s := Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + +redeclare function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + +redeclare function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state := ThermodynamicState( + d=density_ps(p,s), + T=temperature_ps(p,s), + phase=0, + h=specificEnthalpy_ps(p,s), + p=p, + X=X, + s=s, + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_psX; + + redeclare function extends temperature "return temperature of ideal gas" + algorithm + T := state.T; + end temperature; + + redeclare function extends density "return density of ideal gas" + algorithm + d := state.d; + end density; + +redeclare function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state := ThermodynamicState( + d=density_pT(p,T), + T=T, + phase=0, + h=specificEnthalpy_pTX(p,s), + p=p, + X=X, + s=specificEntropy_pT(p.T), + q=-1, + GVF=-1, + d_l=-1, + d_g=-1); +end setState_pTX; + +redeclare function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h := Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + + redeclare function extends thermalConductivity + "Thermal conductivity of water" + algorithm + lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity( + state.d, + state.T, + state.p, + state.phase); + end thermalConductivity; + + redeclare function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp := Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp := Modelica.Media.Water.IF97_Utilities.cp_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCp; + + redeclare function extends saturationPressure + algorithm + p := Modelica.Media.Water.WaterIF97_base.saturationPressure(T); + end saturationPressure; + + redeclare function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" + algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_dT( + state.d, + state.T, + state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv := Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv := Modelica.Media.Water.IF97_Utilities.cv_ph( + state.p, + state.h, + state.phase); + end if; + annotation (Documentation(info=" +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); + end specificHeatCapacityCv; + + annotation (Documentation(info=" +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index 1b48ebf..cbda809 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,4 +3,5 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester +Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index ebcecad..57e8ba5 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -983,7 +983,7 @@ double getS_modelica() { double getWM_modelica(){ //molecular weight - return dwm/1000; + return dwm/1000; // g/mol to kg/mol } double getDL_modelica(){ @@ -1369,6 +1369,12 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = -1. * ddhdp_d / ddhdd_p; ddddh_p = 1./ddhdd_p; } else { // two-phase region, get derivative of density with respect to enthalpy numerically + + + // TODO + ddddp_h = -1; + ddddh_p = -1; + /* if (debug) printf ("Using two-phase derivatives.\n"); deltaP = 0.00005; // 0.05 Pascal difference pLow = dp - 0.5*deltaP; @@ -1396,6 +1402,7 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + */ } } else { // We have a problem! @@ -1674,7 +1681,7 @@ OUTPUT // Set variables to input values if ( strCompare(in1, in2) ) { sprintf(errormsg,"State variable 1 is the same as state variable 2 (%s)\n",in1.c_str()); - return -1; + return FAIL; } memcpy(dxmol, dxmoltmp, sizeof(dxmoltmp)) ; @@ -1907,12 +1914,15 @@ OUTPUT updateProps(props, lerr); - //int outVal = ders_REFPROP(ders,errormsg,debug); - //if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - //outVal = trns_REFPROP(trns,errormsg,debug); - //if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + // TODO + /* + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + */ if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); diff --git a/_wrapper/src/refpropwrappertest.cpp b/_wrapper/src/refpropwrappertest.cpp new file mode 100644 index 0000000..483f5f2 --- /dev/null +++ b/_wrapper/src/refpropwrappertest.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include "refprop_wrapper.h" +#include "refprop_library.h" +#include +#include + + + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; +// int nX = argc-5; + int DEBUG = 0; + + + +/* + int count; + printf ("This program was called with \"%s\".\n",argv[0]); + if (argc > 1) + { + for (count = 1; count < argc; count++) + { + printf("argv[%d] = %s\n", count, argv[count]); + } + } + else + { + printf("The command had no other arguments.\n"); + } +printf("argc is %li \n",argc); +*/ + + +/* + if (argc<5){ + printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); +// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } +*/ +// usage +// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 + +int nX=2; + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + +x[0] = 0.5; +x[1] = 1.0-x[0]; +//x[2] = 1-x[1]; + + + + + +/* + sumx = 0; + for (i=0;i Date: Tue, 26 Nov 2013 11:17:19 +0100 Subject: [PATCH 42/57] Some more playing araound --- _wrapper/Makefile | 9 +- _wrapper/cpptest/cpp_wrapped.cpp | 178 ++++++++++++++++-------- _wrapper/cpptest/refpropwrappertest.cpp | 160 +++++++++++++++++++++ 3 files changed, 283 insertions(+), 64 deletions(-) create mode 100644 _wrapper/cpptest/refpropwrappertest.cpp diff --git a/_wrapper/Makefile b/_wrapper/Makefile index a77465a..2581cb0 100644 --- a/_wrapper/Makefile +++ b/_wrapper/Makefile @@ -140,9 +140,12 @@ $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION): $(SRCDIR)/$(LIBFILE).o .PHONY : test test : $(BINDIR)/$(THETEST) -$(BINDIR)/$(THETEST) : #$(SRCDIR)/$(THETEST).o - $(CPPC) $(DEBUGFLAGS) -o $(SRCDIR)/$(LIBFILE).o -c $(SRCDIR)/$(LIBFILE).cpp $(LIBS) - $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) +# $(BINDIR)/$(THETEST) : #$(SRCDIR)/$(THETEST).o +# $(CPPC) $(DEBUGFLAGS) -o $(SRCDIR)/$(LIBFILE).o -c $(SRCDIR)/$(LIBFILE).cpp $(LIBS) +# $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) $(SRCDIR)/$(THETEST).cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) + +$(BINDIR)/$(THETEST) : $(SRCDIR)/$(LIBFILE).o ./cpptest/cpp_wrapped.cpp + $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) ./cpptest/cpp_wrapped.cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) # .PHONY : ian # ian : $(BINDIR)/$(THETEST).ian diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index 6f523e5..15ba671 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -8,47 +8,25 @@ #include #include +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define refpropcharlong 10000 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + int main(int argc, char* argv[]){ - //char fluidname[255]; char errormsg[255]; double* x; double *props; double *ders; double *trns; - double sumx; - int i; -// int nX = argc-5; int DEBUG = 0; - -/* - int count; - printf ("This program was called with \"%s\".\n",argv[0]); - if (argc > 1) - { - for (count = 1; count < argc; count++) - { - printf("argv[%d] = %s\n", count, argv[count]); - } - } - else - { - printf("The command had no other arguments.\n"); - } -printf("argc is %li \n",argc); -*/ - -/* - if (argc<5){ - printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); -// printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); - return 1; - } -*/ -// usage -// refpropwrappertest "pT" "isobutan|propane" 1e5 293 "c:\\Program Files (x86)\\REFPROP" .1 - /* Define some new functions to access low-level refprop routines. * @@ -70,8 +48,10 @@ printf("argc is %li \n",argc); # if defined(__ISWINDOWS__) char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; + char theSepChar[2] = "\\"; # elif defined(__ISLINUX__) char thepathChar[255] = "/opt/refprop"; + char theSepChar[2] = "/"; # endif // Allocate space for objects @@ -87,7 +67,9 @@ printf("argc is %li \n",argc); double p = 50e5; double h = 3e5; double dh = 25e5; - int N = 50; + + int N = 75; // steps in enthalpy + int M = 15; // repetitions double res = 0.0; double h_in = 0.0; @@ -96,40 +78,114 @@ printf("argc is %li \n",argc); int decimals = 4; int width = 10; char buffer [50]; - //n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); - // printf ("[%s] is a string %d chars long\n",buffer,n); - std::ostringstream out1,out2; - // Then at the beginning: + std::ostringstream out; + + // Get the time, calculate and get the time again time_t tstart, tend; tstart = time(0); - - for (int count = 0; count < N; count++) { - h_in = h + dh * count / (N - 1); - res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG); - sprintf (buffer, "d = %8.4f [kg/m3]",props[4]); - out1 << buffer << std::endl; - sprintf (buffer, "T = %8.4f [K]",props[2]); - out1 << buffer << std::endl << std::endl; + for (int i = 0; i < M; i++) { + for (int count = 0; count < N; count++) { + h_in = h + dh * count / (N - 1); + res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG); + sprintf (buffer, "d = %8.4f [kg/m3]",props[4]); + out << buffer << std::endl; + sprintf (buffer, "T = %8.4f [K]",props[2]); + out << buffer << std::endl << std::endl; + } } - - // And finally before the end: tend = time(0); - out2 << "It took " << difftime(tend, tstart) << " second(s)." << std::endl; - - - //printf("%s", out1.str().c_str()); - - printf("%s", out2.str().c_str()); - - -// myString1 << "It took " << difftime(tend, tstart) << " second(s)." -// << std::endl; -// printf("%s", myString1.str().c_str()); - - - + if (N*M<10) { + printf("%s", out.str().c_str()); + } else { + printf("\nThere were %d calls to the wrapper. \n", N*M); + } + int deltat = difftime(tend, tstart); + printf("It took %d second(s) with an average time per call of %8.4f ms.\n",deltat,deltat*1e3/N/M); + + + // Do the same for the unwrapped functions + +// char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], +// herr[errormessagelength+1],hfmix[refpropcharlength+1]; +// +// double xliq[ncmax],xvap[ncmax],f[ncmax]; +// double wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas; +// double t=100.0; +// double dl,dv; +// long j=1 ,lerr = 0, i=0, ierr=0; +// double d=0.0,q=0.0,e=0.0,s=0.0,cv=0.0,cp=0.0,w=0.0,b=0.0,c=0.0, +// dpdrho,d2pdd2,dpdt,dhdt_d,dhdt_p,dhdp_t,dhdp_d, +// sigma,dhdd_t,dhdd_p,eta,tcx,pp,tt,hjt,h1,dd; +// +// strcpy(hf,thepathChar); +// strcat(hf,theSepChar); +// strcat(hf,"ammoniaL.fld|"); +// strcat(hf,thepathChar); +// strcat(hf,theSepChar); +// strcat(hf,"water.fld"); +// +// strcpy(hfmix,thepathChar); +// strcat(hfmix,theSepChar); +// strcat(hfmix,"fluids"); +// strcat(hfmix,theSepChar); +// strcat(hfmix,"hmx.bnc"); +// +// strcpy(hrf,"DEF"); +// strcpy(herr,"Ok"); +// +// +//// SETUPdll_POINTER SETUPdll; +//// WMOLdll_POINTER WMOLdll; +//// PHFLSHdll_POINTER PHFLSHdll; +// +// //...Call SETUP to initialize the program +// //long ,char*,char*,char*,long ,char*,long ,long ,long ,long +// SETUPdll(i, hf, hfmix, hrf, ierr, herr);//, +// //refpropcharlength*ncmax,refpropcharlength, +// //lengthofreference,errormessagelength); +// +// if (ierr != 0) printf("%s\n",herr); +// +// WMOLdll(x,wm); +// printf("WM, %10.4f\n",wm); +// +// double hmol = h*wm/1000.0; +// double dhmol = dh*wm/1000.0; +// double pkpa = p/1000.0; +// +// //printf("hmol, pkpa %10.4f, %10.4f\n",hmol,pkpa); +// +// //PHFLSHdll (&pkpa,&hmol,x,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); +// //printf("T, D, Pkpa, hmol from PHFLSH %10.4f,%10.4f,%10.4f,%10.4f\n",tt,dd,pkpa,hmol); +// +// +// +// +// tstart = time(0); +// for (int i = 0; i < M; i++) { +// for (int count = 0; count < N; count++) { +// h_in = hmol + dhmol * count / (N - 1); +// PHFLSHdll(pkpa,h_in,x,tt,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); +// sprintf (buffer, "d = %8.4f [kg/m3]",dd); +// out << buffer << std::endl; +// sprintf (buffer, "T = %8.4f [K]",tt); +// out << buffer << std::endl << std::endl; +// } +// } +// tend = time(0); +// +// if (N*M<10) { +// printf("%s", out.str().c_str()); +// } else { +// printf("\nThere were %d calls to REFPROP. \n", N*M); +// } +// +// deltat = difftime(tend, tstart); +// printf("It took %d second(s) with an average time per call of %8.4f ms.\n",deltat,deltat*1e3/N/M); + + printf("%s\n"," "); return 0; } diff --git a/_wrapper/cpptest/refpropwrappertest.cpp b/_wrapper/cpptest/refpropwrappertest.cpp new file mode 100644 index 0000000..18c5cba --- /dev/null +++ b/_wrapper/cpptest/refpropwrappertest.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include "refprop_wrapper.h" + +//double density(char* fluidname_in, double p, double t, double* x, char* REFPROP_PATH); +//double density(char* fluidname_in, double p, double t); +//double density(double p, double t); +//char *str_replace(char *str, char *search, char *replace, long *count); + +int main(int argc, char* argv[]){ + double p,t,d; + char fluidname[255]; + char errormsg[255]; + double* x; + double *props; + double *ders; + double *trns; + double sumx; + int i; + int nX = argc-5; + int DEBUG = 1; + + if (argc<5){ +// printf("usage: refpropwrappertest.exe statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: refpropwrappertest \"pT\" \"isobutan|propane\" 1e5 293 \"d:\\Programme\\REFPROP\\\" .1"); + printf("usage: refpropwrappertest statevars fluidname1|fluidname2|... statevar1 statevar2 REFPROPdir massfractionComponent1 \nexample: ./bin/refpropwrappertest \"pT\" \"ISOBUTAN|PROPANE\" 1e5 293 \"/opt/refprop/\" .1\n"); + return 1; + } + + x = (double*) calloc(nX,sizeof(double)); + props=(double*) calloc(16+2*nX,sizeof(double)); + ders=(double*) calloc(21,sizeof(double)); + trns=(double*) calloc(3,sizeof(double)); + + + sumx = 0; + for (i=0;i Date: Tue, 26 Nov 2013 14:40:38 +0100 Subject: [PATCH 43/57] New test routine --- _wrapper/Makefile | 3 + _wrapper/cpptest/cpp_wrapped.cpp | 221 ++++++++++++++----------------- _wrapper/cpptest/cpp_wrapped.h | 62 +++++++++ 3 files changed, 161 insertions(+), 125 deletions(-) create mode 100644 _wrapper/cpptest/cpp_wrapped.h diff --git a/_wrapper/Makefile b/_wrapper/Makefile index 2581cb0..4b6ba10 100644 --- a/_wrapper/Makefile +++ b/_wrapper/Makefile @@ -147,6 +147,9 @@ test : $(BINDIR)/$(THETEST) $(BINDIR)/$(THETEST) : $(SRCDIR)/$(LIBFILE).o ./cpptest/cpp_wrapped.cpp $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) ./cpptest/cpp_wrapped.cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) + +# $(CPPC) $(DEBUGFLAGS) -o $(BINDIR)/$(THETEST) ./cpptest/cpp_wrapped.cpp $(SRCDIR)/$(LIBFILE).o $(LIBS) + # .PHONY : ian # ian : $(BINDIR)/$(THETEST).ian # diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index 15ba671..1c2a37b 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -3,21 +3,11 @@ #include #include #include -#include "../src/refprop_wrapper.h" -#include "../src/refprop_library.h" #include #include - -// Some constants for REFPROP... defined by macros for ease of use -#define refpropcharlength 255 -#define refpropcharlong 10000 -#define filepathlength 255 -#define lengthofreference 3 -#define errormessagelength 255 -#define ncmax 20 // Note: ncmax is the max number of components -#define numparams 72 -#define maxcoefs 50 - +#include "../src/refprop_library.h" +#include "../src/refprop_wrapper.h" +#include "cpp_wrapped.h" int main(int argc, char* argv[]){ char errormsg[255]; @@ -27,23 +17,6 @@ int main(int argc, char* argv[]){ double *trns; int DEBUG = 0; - - /* Define some new functions to access low-level refprop routines. - * - * The new functions should be used to compare the speed of the wrapper to the speed - * of the Fortran code and the Matlab implementation. - */ - -//# if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) -//# define __ISWINDOWS__ -//# include -//# define _CRT_SECURE_NO_WARNINGS -//# elif __APPLE__ -//# define __ISAPPLE__ -//# elif __linux -//# define __ISLINUX__ -//# endif - int nX=2; // Number of components # if defined(__ISWINDOWS__) @@ -64,23 +37,23 @@ int main(int argc, char* argv[]){ x[0] = 0.2; x[1] = 1.0 - x[0]; - double p = 50e5; - double h = 3e5; - double dh = 25e5; + double p = 50.e5; + double h = 3.0e5; + double dh = 25e1; - int N = 75; // steps in enthalpy - int M = 15; // repetitions + int N = 390; // steps in enthalpy + int M = 253; // repetitions double res = 0.0; double h_in = 0.0; // Format the output properly - int decimals = 4; - int width = 10; - char buffer [50]; + char buffer [100]; + int limit = 10; std::ostringstream out; + out << std::endl; // Get the time, calculate and get the time again time_t tstart, tend; @@ -89,103 +62,101 @@ int main(int argc, char* argv[]){ for (int count = 0; count < N; count++) { h_in = h + dh * count / (N - 1); res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG); - sprintf (buffer, "d = %8.4f [kg/m3]",props[4]); - out << buffer << std::endl; - sprintf (buffer, "T = %8.4f [K]",props[2]); - out << buffer << std::endl << std::endl; + if (N*M +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +#if defined(__ISWINDOWS__) +# define CALLCONV __stdcall +# define SETUPdll SETUPdll +# define WMOLdll WMOLdll +# define XMOLEdll XMOLEdll +# define PHFLSHdll PHFLSHdll +#elif defined(__ISLINUX__) +# define CALLCONV +# define SETUPdll setupdll_ +# define WMOLdll wmoldll_ +# define XMOLEdll xmoledll_ +# define PHFLSHdll phflshdll_ +#endif + +typedef void (CALLCONV *SETUPdll_POINTER)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); +typedef void (CALLCONV *WMOLdll_POINTER)(double *,double &); +typedef void (CALLCONV *XMOLEdll_POINTER)(double *,double *,double &); +typedef void (CALLCONV *PHFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); + +//SETUPdll_POINTER SETUPdll; +//WMOLdll_POINTER WMOLdll; +//PHFLSHdll_POINTER PHFLSHdll; + +extern SETUPdll_POINTER SETUPdll; +extern WMOLdll_POINTER WMOLdll; +extern XMOLEdll_POINTER XMOLEdll; +extern PHFLSHdll_POINTER PHFLSHdll; + +#endif From 256655e308a7bc1c06ea36650577f375433f6606 Mon Sep 17 00:00:00 2001 From: jowr Date: Tue, 26 Nov 2013 16:23:11 +0100 Subject: [PATCH 44/57] started to add some c functions --- _wrapper/cpptest/cpp_wrapped.cpp | 6 +- _wrapper/cpptest/refprop_c.c | 341 +++++++++++++++++++++++++++++++ _wrapper/cpptest/refprop_c.h | 33 +++ 3 files changed, 377 insertions(+), 3 deletions(-) create mode 100644 _wrapper/cpptest/refprop_c.c create mode 100644 _wrapper/cpptest/refprop_c.h diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index 1c2a37b..a4b514a 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -39,10 +39,10 @@ int main(int argc, char* argv[]){ double p = 50.e5; double h = 3.0e5; - double dh = 25e1; + double dh = 2.5e6; - int N = 390; // steps in enthalpy - int M = 253; // repetitions + int N = 500; // steps in enthalpy + int M = 1; // repetitions double res = 0.0; double h_in = 0.0; diff --git a/_wrapper/cpptest/refprop_c.c b/_wrapper/cpptest/refprop_c.c new file mode 100644 index 0000000..e4f9ed8 --- /dev/null +++ b/_wrapper/cpptest/refprop_c.c @@ -0,0 +1,341 @@ +// EX_C2.c written by: +// Ian Bell +// Herrick Labs +// Purdue University +// ibell@purdue.edu +// August 31, 2010 + +// heavily based on example file EX_C1.cpp by + +// Chris Muzny +// N.I.S.T. +// Chemical Science and Technology Laboratory +// Physical and Chemical Properties of Fluids Division +// (303) 497-5549 +// chris.muzny@nist.gov + +//This program demonstrates explicitly linking the subroutines available in +// refprop.dll. In order to link this code refprop1.h +// must be available in the current directory. When executing refprop.dll must be in the dll +// search path (current directory and $PATH). + +#if defined(__ISWINDOWS__) +#include +#elif defined(__ISLINUX__) +#include +#endif + +#include +#include +#include +#include +#include "refprop_c.h" + + +// Some constants... +#define refpropcharlength 255 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +int main(int argc, char* argv[]) +{ + int count; + clock_t myt; + + double dh; + int N=500; + double* T_save; + double* h_in; + + char *FLD_PATH; + + double x[ncmax],xliq[ncmax],xvap[ncmax],f[ncmax],xmol[ncmax]; + + long i,ierr=0; + char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], + herr[errormessagelength+1],hfmix[refpropcharlength+1]; + + double wm,ttp,tnbp,tc,pc,dc,zc,acf,dip,rgas; + long info_index=1; + double t=100.0; + double p,dl,dv; + long j=1; + double d=0.0,q=0.0,e=0.0,h=0.0,s=0.0,cv=0.0,cp=0.0,w=0.0,b=0.0,c=0.0, + dpdrho,d2pdd2,dpdt,dhdt_d,dhdt_p,dhdp_t,dhdp_d, + sigma,dhdd_t,dhdd_p,eta,tcx,pp,tt,hjt,h1,dd; + long tmp_int=0; + long kr=1; + + //xkg = (double*) calloc(ncmax,sizeof(double)); + + //double xkg[ncmax]; + //double wmix; + double hmol,pkpa; + + +#if defined(__ISWINDOWS__) + HINSTANCE RefpropdllInstance; + RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\refprop.dll"); + PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(RefpropdllInstance,"SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) GetProcAddress(RefpropdllInstance,"XMOLEdll"); +#elif defined(__ISLINUX__) + void *RefpropdllInstance = NULL; + RefpropdllInstance = dlopen("librefprop.so", RTLD_LAZY); + PHFLSHdll = (fp_PHFLSHdllTYPE) dlsym(RefpropdllInstance, "PHFLSHdll"); + SETUPdll = (fp_SETUPdllTYPE) dlsym(RefpropdllInstance, "SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) dlsym(RefpropdllInstance, "XMOLEdll"); +#endif + + + +// Now use the functions. + +// Refprop variables that need to be defined +// +// nc = Number of components in the mixture +// x[NumberOfComponentsInMixtures] = Mole fraction of each component +// ierr = An integer flag defining an error +// hf[] = a character array defining the fluids in a mixture +// hrf[] = a character array denoting the reference state +// herr[] = a character array for storing a string - Error message +// hfmix[] a character array defining the path to the mixture file + + + //Exlicitely set the fluid file PATH +# if defined(__ISWINDOWS__) + FLD_PATH = "C:\\Program Files (x86)\\REFPROP\\fluids"; + char theSepChar[2] = "\\"; +# elif defined(__ISLINUX__) + FLD_PATH = "/opt/refprop"; + char theSepChar[2] = "/"; +# endif +// strcpy(hf,FLD_PATH); +// strcpy(hfmix,FLD_PATH); + + //...initialize the program and set the pure fluid component name + //i=1; + //strcpy(hf,"nitrogen.fld"); + //strcpy(hfmix,"hmx.bnc"); + //strcpy(hrf,"DEF"); + //strcpy(herr,"Ok"); + +//...For a mixture, use the following setup instead of the lines above. + // Use "|" as the file name delimiter for mixtures + i=2; + strcpy(hf,FLD_PATH); + strcat(hf,theSepChar); + strcat(hf,"ammoniaL.fld|"); + strcat(hf,FLD_PATH); + strcat(hf,theSepChar); + strcat(hf,"water.fld"); + + strcpy(hfmix,FLD_PATH); + strcat(hfmix,theSepChar); + strcat(hfmix,"HMX.BNC"); + + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + + x[0]=.5; //Air composition + x[1]=.5; + //x[2]=.2096; + + //...Call SETUP to initialize the program + SETUPdll(&i, hf, hfmix, hrf, &ierr, herr, + refpropcharlength*ncmax,refpropcharlength, + lengthofreference,errormessagelength); + //long ,char*,char*,char*,long ,char*,long ,long ,long ,long + if (ierr != 0) printf("%s\n",herr); + + p=50e5; + h=3e5; + + //wmix=1; + //xkg=1; + //XMOLEdll (x,&xkg,&wmix); + + XMOLEdll (x,xmol,&wm); + //WMOLdll(x,&wm); + //printf("WM, %10.4f\n",wm); + + hmol = h*wm/1000; + pkpa = p/1000; + + printf("hmol, pkpa %10.4f, %10.4f\n",hmol,pkpa); + + PHFLSHdll (&pkpa,&hmol,xmol,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, Pkpa, hmol from PHFLSH %10.4f,%10.4f,%10.4f,%10.4f\n",tt,dd,pkpa,hmol); + + + dh=25e5; + T_save = (double*) calloc(N,sizeof(double)); + h_in = (double*) calloc(N,sizeof(double)); + + // Get the time, calculate and get the time again + time_t tstart, tend; + tstart = time(0); + + for (count = 0; count < N; count++) + { + h_in[count] = (h+dh*count/(N-1))*wm/1000; + + PHFLSHdll (&pkpa,&h_in[count],xmol,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + + T_save[count] = tt; + + //printf("T=%f [K]\n",T_save[count]); + } + tend = time(0); + + int deltat = difftime(tend, tstart)*1e3; + printf("Time per call: %8.4f milliseconds\n", deltat/(N*1.0)); + +/* + + INFOdll(&info_index,&wm,&ttp,&tnbp,&tc,&pc,&dc,&zc,&acf,&dip,&rgas); + printf("WM,ACF,DIP,TTP,TNBP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",wm,acf,dip,ttp,tnbp); + printf("TC,PC,DC,RGAS %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",tc,pc,dc,rgas); +//...Calculate molecular weight of a mixture +// wm=WMOLdll(x) + +//...Get saturation properties given t,x; for i=1: x is liquid phase +//..... for i=2: x is vapor phase + + + i=1; + SATTdll(&t,x,&i,&p,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + i=2; + SATTdll(&t,x,&i,&p,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("P,Dl,Dv,xl[0],xv[0] %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",p,dl,dv,xliq[0],xvap[0]); + +//...Calculate saturation properties at a given p. i is same as SATT + i=2; + SATPdll(&p,x,&i,&t,&dl,&dv,xliq,xvap,&ierr,herr,errormessagelength); + printf("T,Dl,Dv,xl(1),xv(1) %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,dl,dv,xliq[0],xvap[0]); + +//...Other saturation routines are given in SAT_SUB.FOR + + t=300.0; + p=20000.0; + +//...Calculate d from t,p,x +//...If phase is known: (j=1: Liquid, j=2: Vapor) + + TPRHOdll(&t,&p,x,&j,&tmp_int,&d,&ierr,herr,errormessagelength); + printf("T,P,D %10.4f,%10.4f,%10.4f\n",t,p,d); + +//...If phase is not known, call TPFLSH +//...Calls to TPFLSH are much slower than TPRHO since SATT must be called first. +//.....(If two phase, quality is returned as q) + + TPFLSHdll(&t,&p,x,&d,&dl,&dv,xliq,xvap,&q,&e,&h,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T,P,D,H,CP %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n",t,p,d,h,cp); + +//...Calculate pressure (p), internal energy (e), enthalpy (h), entropy (s), +//.....isochoric (cv) and isobaric (cp) heat capacities, speed of sound (w), +//.....and Joule-Thomson coefficient (hjt) from t,d,x +//.....(subroutines THERM2 and THERM3 contain more properties, see PROP_SUB.FOR) + THERMdll(&t,&d,x,&p,&e,&h,&s,&cv,&cp,&w,&hjt); + +//...Calculate pressure + PRESSdll(&t,&d,x,&p); + +//...Calculate fugacity + FGCTYdll(&t,&d,x,f); + +//...Calculate second and third virial coefficients + VIRBdll (&t,x,&b); + VIRCdll (&t,x,&c); + printf("F,B,C %10.4f,%10.4f,%10.4f\n",f[0],b,c); +// +//...Calculate the derivatives: dP/dD, d^2P/dD^2, dP/dT (D indicates density) +//...(dD/dP, dD/dT, and dB/dT are also available, see PROP_SUB.FOR) + DPDDdll (&t,&d,x,&dpdrho); + DPDD2dll (&t,&d,x,&d2pdd2); + DPDTdll (&t,&d,x,&dpdt); + printf("dP/dD,d2P/dD2,dP/dT %10.4f,%10.4f,%10.4f\n",dpdrho,d2pdd2,dpdt); + + +//...Calculate derivatives of enthalpy with respect to T, P, and D + DHD1dll(&t,&d,x,&dhdt_d,&dhdt_p,&dhdd_t,&dhdd_p,&dhdp_t,&dhdp_d); + printf("Enthalpy derivatives %10.4f,%10.4f,%10.4f,%10.4f,%10.4f\n", + dhdt_d,dhdt_p,dhdd_t,dhdd_p/1000.0,dhdp_t); +//...Calculate surface tension + SURFTdll (&t,&dl,x,&sigma,&ierr,herr,errormessagelength); + printf("T,SURF. TN. %10.4f,%10.4f\n",t,sigma); + +//...Calculate viscosity (eta) and thermal conductivity (tcx) + TRNPRPdll (&t,&d,x,&eta,&tcx,&ierr,herr,errormessagelength); + printf("VIS.,TH.CND. %10.4f,%10.4f\n",eta,tcx*1000.0); + +//...General property calculation with inputs of t,d,x + TDFLSHdll (&t,&d,x,&pp,&dl,&dv,xliq,xvap,&q,&e,&h1,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from TDFLSH %10.4f,%10.4f,%10.4f\n",t,d,pp/1000.0); + +//...General property calculation with inputs of p,d,x + PDFLSHdll (&p,&d,x,&tt,&dl,&dv,xliq,xvap,&q,&e,&h1,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PDFLSH %10.4f,%10.4f,%10.4f\n",tt,d,p/1000.0); + +//...General property calculation with inputs of p,h,x + PHFLSHdll (&p,&h,x,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PHFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + +//...General property calculation with inputs of p,s,x + PSFLSHdll (&p,&s,x,&tt,&dd,&dl,&dv,xliq,xvap,&q,&e,&h1,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from PSFLSH %10.4f,%10.4f,%10.4f\n",tt,dd,p/1000.0); + +//...General property calculation with inputs of d,h,x + DHFLSHdll (&d,&h,x,&tt,&pp,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from DHFLSH %10.4f,%10.4f,%10.4f\n",tt,d,pp/1000.0); + +//...General property calculation with inputs of t,h,x +// kr--flag specifying desired root for multi-valued inputs: +// 1=return lower density root +// 2=return higher density root + + THFLSHdll (&t,&h,x, + &kr,&pp,&dd,&dl,&dv,xliq,xvap,&q,&e,&s,&cv,&cp,&w,&ierr,herr,errormessagelength); + printf("T, D, P from THFLSH %10.4f,%10.4f,%10.4f\n",t,dd,pp/1000.0); + +//...Other general property calculation routines are given in FLSH_SUB.FOR +//...and FLASH2.FOR + +//...Calculate melting pressure + t=100.0; + MELTTdll (&t,x,&p,&ierr,herr,errormessagelength); + printf("Melting pressure(MPa) %10.4f,%10.4f\n",p/1000.0,t); + +//...Calculate melting temperature + MELTPdll (&p,x,&tt,&ierr,herr,errormessagelength); + printf("Melting temperature(K)%10.4f,%10.4f\n",tt,p/1000.0); + +//...Calculate sublimation pressure + t=200.0; + SUBLTdll (&t,x,&p,&ierr,herr,errormessagelength); + printf("Sublimation pr.(kPa) %10.4f,%10.4f\n",p,t); + +//...Calculate sublimation temperature + SUBLPdll (&p,x,&tt,&ierr,herr,errormessagelength); + printf("Sublimation temp.(K) %10.4f,%10.4f\n",tt,p); + +//...Get limits of the equations and check if t,d,p is a valid point +//...Equation of state +// call LIMITK ('EOS',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) +//...Viscosity equation +// call LIMITK ('ETA',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) +//...Thermal conductivity equation +// call LIMITK ('TCX',1,t,d,p,tmin,tmax,Dmax,pmax,ierr,herr) + +//...Other routines are given in UTILITY.FOR + +*/ + + return 0; +} +//--------------------------------------------------------------------------- diff --git a/_wrapper/cpptest/refprop_c.h b/_wrapper/cpptest/refprop_c.h new file mode 100644 index 0000000..9abea59 --- /dev/null +++ b/_wrapper/cpptest/refprop_c.h @@ -0,0 +1,33 @@ + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +#if defined(__ISWINDOWS__) +#include +#elif defined(__ISLINUX__) +#include +#endif + +#if defined(__ISWINDOWS__) +// For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" +typedef void (__stdcall *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); +typedef void (__stdcall *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); +typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double *); +#elif defined(__ISLINUX__) +// For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" +typedef void ( *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); +typedef void ( *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); +typedef void ( *fp_XMOLEdllTYPE)(double *,double *,double *); +#endif + +//Define explicit function pointers +fp_PHFLSHdllTYPE PHFLSHdll; +fp_SETUPdllTYPE SETUPdll; +fp_XMOLEdllTYPE XMOLEdll; From 439a0233bf2c52266c439b904842259bf19b1465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Wed, 27 Nov 2013 11:12:26 +0100 Subject: [PATCH 45/57] Modelica path now used to load dll.. (good in windows if old dll's are in environment variables :-) --- _wrapper/src/BuildLIB-VS2010.bat | 10 ++++++++++ _wrapper/src/refprop_wrapper.cpp | 22 ++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 _wrapper/src/BuildLIB-VS2010.bat diff --git a/_wrapper/src/BuildLIB-VS2010.bat b/_wrapper/src/BuildLIB-VS2010.bat new file mode 100644 index 0000000..22910d8 --- /dev/null +++ b/_wrapper/src/BuildLIB-VS2010.bat @@ -0,0 +1,10 @@ +REM ******** set the variables ************ +REM call both to ensure that one works +call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" +call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" + +REM ******* compile all the sources from CoolProp *************** +cl /c /Ox /fp:fast /MD /EHsc refprop_wrapper.cpp + +lib refprop_wrapper.obj +erase *.obj diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 57e8ba5..29ccef5 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #if defined(__ISWINDOWS__) @@ -608,13 +609,17 @@ std::string resolve_error(std::string in1, long lerr, char* errormsg) { * Load the library and handle all the * platform specific stuff. */ -double loadLibrary() { +double loadLibrary(std::string sPath) { if (RefpropdllInstance == NULL) { // Refprop is not loaded #if defined(__ISWINDOWS__) #if defined(UNICODE) - RefpropdllInstance = LoadLibraryW((LPCWSTR)libName); + sPath.append((LPCWSTR)pathSep); + sPath.append((LPCWSTR)libName); + RefpropdllInstance = LoadLibraryW(sPath.c_str()); #else - RefpropdllInstance = LoadLibrary((LPCSTR)libName); + sPath.append((LPCSTR)pathSep); + sPath.append((LPCSTR)libName); + RefpropdllInstance = LoadLibrary(sPath.c_str()); // this works in cpp tester, but not in Modelica.. #endif #elif defined(__ISLINUX__) RefpropdllInstance = dlopen(libName, RTLD_LAZY); @@ -790,10 +795,13 @@ double setFunctionPointers() { * Make sure the library is loaded * properly and set pointers. */ -double initRefprop() { +double initRefprop(std::string sPath) { + + //std::string rPath = std::string(sPath); + if (RefpropdllInstance == NULL) { if (debug) printf ("Library not loaded, trying to do so.\n"); - if (loadLibrary() != OK) { + if (loadLibrary(sPath) != OK) { printf("Refprop library %s cannot be loaded, make sure you ",libName); printf("installed it properly.\n"); return FAIL; @@ -827,7 +835,9 @@ double setFluids(std::string sPath, std::string sFluids, char* error){ // sPath: "/opt/refprop" or "C:\Program Files\Refprop" // sFluids: "pentane|butane" or "air" - if (initRefprop() != OK){ + //std::string rPath = std::string(sPath); + + if (initRefprop(sPath) != OK){ std::cerr << "ERROR: library not loaded.\n"; std::terminate(); } From bbdfd645e0efd4b32ed21db13e85ea9e19a435ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Thu, 5 Dec 2013 22:43:35 +0100 Subject: [PATCH 46/57] I have included analytical derivatives of density wrt enthalpy and pressure. Still missing density derivative wrt mass fraction... I have reduced the number of variables in ders[]. I also uploaded a Modelica Model that compares the analytical derivative and numerical ones... --- Testers/NH3_Water_setStateModel.mo | 39 +++++ _wrapper/cpptest/cpp_wrapped.cpp | 25 ++-- _wrapper/src/refprop_wrapper.cpp | 224 +++++++++++++++++------------ package.mo | 5 +- 4 files changed, 192 insertions(+), 101 deletions(-) create mode 100644 Testers/NH3_Water_setStateModel.mo diff --git a/Testers/NH3_Water_setStateModel.mo b/Testers/NH3_Water_setStateModel.mo new file mode 100644 index 0000000..db94a0d --- /dev/null +++ b/Testers/NH3_Water_setStateModel.mo @@ -0,0 +1,39 @@ +within REFPROP2Modelica.Testers; +model NH3_Water_setStateModel + +package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState state; +// Medium.SaturationProperties sat; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + Medium.Density d; + +Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; + +Real q; + +Real dddh_pX; +Real dddp_hX; +Real dddh_pX_num; +Real dddp_hX_num; + +equation + p=50e5; + h=5e5 + time*25e5; + X={0.2,0.8}; + + state = Medium.setState_phX(p,h,X); + q = Medium.vapourQuality(state); + + d = Medium.density(state); + + dddh_pX = Medium.density_derh_p(state); + dddh_pX_num = Medium.density(Medium.setState_phX(p,h+1,X))-d; + + dddp_hX = Medium.density_derp_h(state); + dddp_hX_num = Medium.density(Medium.setState_phX(p+1,h,X))-d; + +end NH3_Water_setStateModel; diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index a4b514a..19722b0 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -38,10 +38,10 @@ int main(int argc, char* argv[]){ x[1] = 1.0 - x[0]; double p = 50.e5; - double h = 3.0e5; - double dh = 2.5e6; + double h = 20.0e5; + double dh = 0e6; - int N = 500; // steps in enthalpy + int N = 2; // steps in enthalpy int M = 1; // repetitions double res = 0.0; @@ -49,8 +49,7 @@ int main(int argc, char* argv[]){ // Format the output properly char buffer [100]; - int limit = 10; - + int limit = 100; std::ostringstream out; out << std::endl; @@ -66,6 +65,8 @@ int main(int argc, char* argv[]){ sprintf (buffer, "d = %8.4f [kg/m3]",props[4]); out << buffer << std::endl; sprintf (buffer, "T = %8.4f [K]",props[2]); + out << buffer << std::endl; + sprintf (buffer, "Ders = %8.0f , %8.12f , %8.1f , %8.1f , %8.12f , %8.8f , %8.1f , %8.2f , %8.2f , %8.6f , %8.9f , %8.9f, %8.1f",ders[0],ders[1],ders[2],ders[3],ders[4],ders[5],ders[6],ders[7],ders[8],ders[9],ders[19],ders[20],ders[6]); out << buffer << std::endl << std::endl; } } @@ -73,7 +74,7 @@ int main(int argc, char* argv[]){ tend = time(0); if (N*M 1.) { // single-phase region if (debug) printf ("Using single-phase derivatives.\n"); - ddddp_h = -1. * ddhdp_d / ddhdd_p; - ddddh_p = 1./ddhdd_p; - } else { // two-phase region, get derivative of density with respect to enthalpy numerically + + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + + ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; + ddddh_p = -dbeta*dd/dCp; + } else { // two-phase region, get derivative of density - // TODO - ddddp_h = -1; - ddddh_p = -1; - /* - if (debug) printf ("Using two-phase derivatives.\n"); - deltaP = 0.00005; // 0.05 Pascal difference - pLow = dp - 0.5*deltaP; - pHigh = dp + 0.5*deltaP; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); - PHFLSHdll(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); - PHFLSHdll(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddp_h_num from %f and %f.\n",rhoHigh,rhoLow); - ddddp_h = (rhoHigh-rhoLow) / (pHigh-pLow); - - // get derivative of density with respect to enthalpy numerically - deltaH = 0.05; // 0.05 Joule total difference - hLow = dh - 0.5*deltaH; - hHigh = dh + 0.5*deltaH; - rhoLow = 0; - rhoHigh = 0; - //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hLow); - PHFLSHdll(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Calling PHFLSH with p=%f and h=%f for derivative.\n",dp,hHigh); - PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); - if (debug) printf("Setting dddh_p_num from %f and %f.\n",rhoHigh,rhoLow); - ddddh_p = (rhoHigh-rhoLow) / (hHigh-hLow); + // These are not computed in two-phase! + dxkappa=noValue; + dbeta=noValue; + + /* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) */ + + //compute saturated vapor state + long kph2 = 2; + double dt_v,ddv_v,dCv_v,dCp_v,dwm_v,dxkappa_v,dbeta_v,h_v,s_v; + SATPdll(dp,dxmol,kph2,dt_v,spare3,ddv_v,spare2,spare1,lerr,errormsg,errormessagelength); + THERM2dll(dt_v, ddv_v, dxmol, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + + + + //compute saturated liquid state + long kph1 = 1; + double dt_l,ddl_l,dCv_l,dCp_l,dwm_l,dxkappa_l,dbeta_l,h_l,s_l; + SATPdll(dp,dxmol,kph1,dt_l,ddl_l,spare3,spare2,spare1,lerr,errormsg,errormessagelength); + THERM2dll(dt_l, ddl_l, dxmol, spare3, spare4, h_l, s_l, dCv_l, dCp_l, dwm_l,spare2, spare10, spare11, spare12, dxkappa_l, dbeta_l, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + + // compute partials + double dvdh_p,dTdp_clasius, dhdpL,dhdpV,dvdpL,dvdpV,dxdp_h,dvdp_h; + // compute drhodh_p + dvdh_p = (1/ddv_v - 1/ddl_l)/(h_v-h_l); + ddddh_p = -dd*dd*dvdh_p; + // compute drhodp_h + dTdp_clasius = (1/ddv_v - 1/ddl_l)/(s_v-s_l); + dhdpL = 1/ddl_l*(1-dbeta_l*dt_l)+dCp_l*dTdp_clasius; + dhdpV = 1/ddv_v*(1-dbeta_v*dt_v)+dCp_v*dTdp_clasius; + dvdpL = dbeta_l*1/ddl_l*dTdp_clasius-dxkappa_l*1/ddl_l; + dvdpV = dbeta_v*1/ddv_v*dTdp_clasius-dxkappa_v*1/ddv_v; + + //TODO - Everything so far is refprop units, but for some reason the quality below must be on mass basic? + double dqmoltmp; + dqmoltmp = dqmol*dwvap/dwm; + dxdp_h = (dhdpL + dqmoltmp * (dhdpV-dhdpL))/(h_l-h_v); + dvdp_h = dvdpL+dxdp_h*(1/ddv_v-1/ddl_l)+dqmoltmp*(dvdpV-dvdpL); + ddddp_h = -dd*dd*dvdp_h; + + + /* + printf("dqmol %f\n", dqmol); + if (dwvap==noValue) + { + printf("dwm %f\n", dwm); + printf("dwvap %f\n", dwvap); + WMOLdll(dxmolv,dwvap); + dqmol = dqmol*dwvap/dwm; + printf("first dqmol %f\n", dqmol); + + } else { + printf("dwm %f\n", dwm); + printf("dwvap %f\n", dwvap); + dqmol = dqmol*dwvap/dwm; + printf("second dqmol %f\n", dqmol); + } + + printf("dqmol %f\n", dqmol); + */ + } } else { // We have a problem! @@ -1926,10 +1974,10 @@ OUTPUT // TODO - /* + int outVal = ders_REFPROP(ders,errormsg,debug); if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - + /* outVal = trns_REFPROP(trns,errormsg,debug); if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); */ diff --git a/package.mo b/package.mo index 273e63d..c2576c6 100644 --- a/package.mo +++ b/package.mo @@ -1,9 +1,12 @@ within ; package REFPROP2Modelica - constant String REFPROP_PATH = "C:\\Program Files\\REFPROP"; + constant String REFPROP_PATH = "C:\\Program Files (x86)\\REFPROP"; // constant String REFPROP_PATH = "/opt/refprop"; + + + annotation(version = "0.2", uses(Modelica(version = "3.2")), Documentation(info="

Documentation is found in the packages. Installation directions are found in both REFPROP packages.

Contact for original implementation:

From 5f80a4b3e94e3cd60810fa3139d5a161d3a9f9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 17 Dec 2013 13:41:16 +0100 Subject: [PATCH 47/57] Made setSat function for saturation properties setSat_pX and setSat_TX, that includes dew and bubble properties. In C wrapper all sat variables are accompanied with sat in the variable name.. Made 2 choices on two-phase partial derivatives. Note that the numerical ones uses only one additional state, and that the more correct method would be to use 2 points, but increases CPU time. Also the analytical ones at constant concentration are pseudo, so they do not include the fact that liquid and vapor properties also depend on concentration. This should however be more quick. Made a choice on calculation of transport properties. --- Interfaces/PartialMixtureTwoPhaseMedium.mo | 43 +- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 419 ++++++++--------- Media/NH3_Water.mo | 6 +- Testers/NH3_Water_setSatModel.mo | 25 + Testers/NH3_Water_setStateModel.mo | 8 +- Testers/PropsMixtureNH3H2O.mo | 3 +- Testers/PropsMixtureTwo.mo | 3 +- _wrapper/cpptest/cpp_wrapped.cpp | 43 +- _wrapper/cpptest/cpp_wrapped.h | 13 +- _wrapper/cpptest/cpp_wrapped2.cpp | 163 +++++++ _wrapper/src/refprop_library.h | 5 + _wrapper/src/refprop_wrapper.cpp | 509 +++++++++++++++++---- _wrapper/src/refprop_wrapper.h | 4 +- 13 files changed, 878 insertions(+), 366 deletions(-) create mode 100644 Testers/NH3_Water_setSatModel.mo create mode 100644 _wrapper/cpptest/cpp_wrapped2.cpp diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index cf5624e..4620b07 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -74,30 +74,34 @@ redeclare replaceable record extends ThermodynamicState //AbsolutePressure p "pressure"; SpecificEntropy s "specific entropy"; //MassFraction X[nX] "Mass fraction of components in kg/kg"; + MassFraction q "vapor quality"; annotation(Documentation(info="")); end ThermodynamicState; replaceable record SaturationProperties "Saturation properties of two phase medium" extends Modelica.Icons.Record; - Temperature Tsat(min=1e-8) "saturation temperature"; + Temperature Tl(min=1e-8) "saturation temperature at bubble line"; + Temperature Tv(min=1e-8) "saturation temperature at dew line"; + AbsolutePressure pl(min=1e-8) "saturation pressure at bubble line"; + AbsolutePressure pv(min=1e-8) "saturation pressure at dew line"; // Real dTp "derivative of Ts wrt pressure"; // DerDensityByPressure ddldp "derivative of dls wrt pressure"; // DerDensityByPressure ddvdp "derivative of dvs wrt pressure"; // DerEnthalpyByPressure dhldp "derivative of hls wrt pressure"; // DerEnthalpyByPressure dhvdp "derivative of hvs wrt pressure"; - // Density dl "density at bubble line (for pressure ps)"; - // Density dv "density at dew line (for pressure ps)"; - // SpecificEnthalpy hl "specific enthalpy at bubble line (for pressure ps)"; - // SpecificEnthalpy hv "specific enthalpy at dew line (for pressure ps)"; - AbsolutePressure psat(min=1e-8) "saturation pressure"; - // SurfaceTension sigma "surface tension"; - // SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; - // SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; - MassFraction X[nX] "Bulk mass fractions"; + Density dl "density at bubble line (for pressure ps)"; + Density dv "density at dew line (for pressure ps)"; + SpecificEnthalpy hl "specific enthalpy at bubble line (for pressure ps)"; + SpecificEnthalpy hv "specific enthalpy at dew line (for pressure ps)"; + SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; + SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; + SurfaceTension sigma "surface tension"; + MassFraction X[nX] "Bulk mass fractions"; + // MolarMass MMl "molar mass bubble line (for pressure ps)"; + // MolarMass MMv "molar mass at dew line (for pressure ps)"; // MassFraction Xl[nX] "Mass fractions of liquid phase"; // MassFraction Xv[nX] "Mass fractions of gaseous phase"; - // annotation(Documentation(info="")); end SaturationProperties; redeclare replaceable model extends BaseProperties( @@ -890,17 +894,18 @@ end temperature; replaceable function vapourQuality "Return vapour quality" input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x "Vapour quality"; + output MassFraction q "Vapour quality"; protected constant SpecificEnthalpy eps = 1e-8; algorithm - x := min(max((specificEnthalpy(state) - bubbleEnthalpy( - setSat_pX( - pressure(state), state.X)))/(dewEnthalpy( - setSat_pX( - pressure(state), state.X)) - bubbleEnthalpy( - setSat_pX( - pressure(state), state.X)) + eps), 0), 1); + // x := min(max((specificEnthalpy(state) - bubbleEnthalpy( + // setSat_pX( + // pressure(state), state.X)))/(dewEnthalpy( + // setSat_pX( + // pressure(state), state.X)) - bubbleEnthalpy( + // setSat_pX( + // pressure(state), state.X)) + eps), 0), 1); + q := state.q; annotation(Documentation(info="")); end vapourQuality; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 4f849d9..ef71955 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -16,6 +16,10 @@ partial package REFPROPMixtureTwoPhaseMedium "Merge all substance names to one string for refprop library"; constant Boolean debugmode=false "print messages in functions and wrapper library if run from command line"; + constant Boolean calcTransport=false; + constant Boolean calcTwoPhaseNumericalDerivatives=false; + constant Boolean calcTwoPhasePsuedoAnalyticalDerivatives=false; + constant FluidConstants[nS] rpConstants( each chemicalFormula="REFPROP Medium", each structureFormula="REFPROP Medium", @@ -43,7 +47,7 @@ partial package REFPROPMixtureTwoPhaseMedium extends Modelica.Icons.Function; protected Real[16 + 2*nX] props; - Real[21] ders; + Real[6] ders; Real[3] trns; String errormsg=StrJoin(fill("xxxx", 64), "") "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; @@ -82,7 +86,10 @@ partial package REFPROPMixtureTwoPhaseMedium phase, REFPROP_PATH, errormsg, - debugmode); + debugmode, + calcTransport, + calcTwoPhaseNumericalDerivatives, + calcTwoPhasePsuedoAnalyticalDerivatives); annotation (Include="#include ", Library="refprop_wrapper"); end getProp_REFPROP; @@ -119,14 +126,26 @@ partial package REFPROPMixtureTwoPhaseMedium + errormsg + "\n"); end getProp_REFPROP_check; + partial function partialSatREFPROP "Declaration of array props" + //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() + extends Modelica.Icons.Function; + protected + Real[12 + 1*nX] satprops; + String errormsg=StrJoin(fill("xxxx", 64), "") + "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; + // initial algorithm + // props :=fill(1, (16 + 2*nX)); + // ders :=fill(1, 19); + // trns :=fill(1, 3); + + end partialSatREFPROP; + function getSatProp_REFPROP "calls C function with property identifier & returns single property" input String what2calc; input String statevar; input String fluidnames; - input Real[:] ders; - input Real[:] trns; - input Real[:] props; + input Real[:] satprops; input Real statevarval; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; input String errormsg; @@ -136,20 +155,19 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevar, fluidnames, - ders, - trns, - props, + satprops, statevarval, X, REFPROP_PATH, errormsg, - debugmode); + debugmode, + calcTransport); annotation (Include="#include ", Library="refprop_wrapper"); end getSatProp_REFPROP; function getSatProp_REFPROP_check "wrapper for getSatProp_REFPROP returning 1 property value with error check" - extends partialREFPROP; + extends partialSatREFPROP; input String what2calc; input String statevar; // input String fluidnames; @@ -162,21 +180,23 @@ partial package REFPROPMixtureTwoPhaseMedium what2calc, statevar, fluidnames, - ders, - trns, - props, + satprops, statevarval, X, errormsg) "just passing through"; //Error string decoding in wrapper-c-function - assert(props[1] == 0 or props[1] == 141, "Errorcode " + String(props[1]) + " in REFPROP wrapper function:\n" + assert(satprops[1] == 0 or satprops[1] == 141, "Errorcode " + String(satprops[1]) + " in REFPROP wrapper function:\n" + errormsg + "\n"); - if props[1] == 141 then + if satprops[1] == 141 then Modelica.Utilities.Streams.print("Saturation properties cannot be calculated, because P > p_crit!..."); val := -999; end if; end getSatProp_REFPROP_check; +redeclare record extends SaturationProperties + "Saturation properties in two-phase region" +end SaturationProperties; + redeclare record extends ThermodynamicState "Adapt this record to the returned values from one REFPROP call." @@ -195,27 +215,28 @@ redeclare record extends ThermodynamicState // DerDensityByPressure ddph // "derivative of density wrt pressure at constant enthalpy"; - Real hjt "isenthalpic Joule-Thompson coefficient [K/Pa]"; - Modelica.SIunits.SpecificHelmholtzFreeEnergy a "Helmholtz energy"; - Modelica.SIunits.SpecificGibbsFreeEnergy f "Gibbs free energy"; +// Real hjt "isenthalpic Joule-Thompson coefficient [K/Pa]"; +// Modelica.SIunits.SpecificHelmholtzFreeEnergy a "Helmholtz energy"; +// Modelica.SIunits.SpecificGibbsFreeEnergy f "Gibbs free energy"; Modelica.SIunits.IsothermalCompressibility kappa "isothermal compressibility"; IsobaricExpansionCoefficient beta "volume expansivity (= 1/V dV/dT = -1/rho dD/dT)"; - DerPressureByDensity dpdrho_T; - DerDerPressureByDensityByDensity d2pdrho2_T; - DerPressureByTemperature dpdT_rho; - DerDensityByTemperature drhodT_p; - DerDensityByPressure drhodp_T; - DerDerPressureByTemperatureByTemperature d2pdT2_rho; - DerDerPressureByTemperatureByDensity d2pdTdrho; - DerEnthalpyByTemperature dhdT_rho "dH/dT at constant density"; - DerEnthalpyByTemperature dhdT_p "dH/dT at constant pressure"; - DerEnthalpyByDensity dhdrho_T "dH/drho at constant temperature"; - DerEnthalpyByDensity dhdrho_p "dH/drho at constant pressure"; - DerEnthalpyByPressure dhdp_T "dH/dP at constant temperature"; - DerEnthalpyByPressure dhdp_rho "dH/dP at constant density"; - +// DerPressureByDensity dpdrho_T; +// DerDerPressureByDensityByDensity d2pdrho2_T; +// DerPressureByTemperature dpdT_rho; +// DerDensityByTemperature drhodT_p; +// DerDensityByPressure drhodp_T; +// DerDerPressureByTemperatureByTemperature d2pdT2_rho; +// DerDerPressureByTemperatureByDensity d2pdTdrho; +// DerEnthalpyByTemperature dhdT_rho "dH/dT at constant density"; +// DerEnthalpyByTemperature dhdT_p "dH/dT at constant pressure"; +// DerEnthalpyByDensity dhdrho_T "dH/drho at constant temperature"; +// DerEnthalpyByDensity dhdrho_p "dH/drho at constant pressure"; +// DerEnthalpyByPressure dhdp_T "dH/dP at constant temperature"; +// DerEnthalpyByPressure dhdp_rho "dH/dP at constant density"; + + DerDensityByEnthalpy drhodX_ph "drho/dh at constant pressure"; DerDensityByEnthalpy drhodh_p "drho/dh at constant pressure"; DerDensityByPressure drhodp_h "drho/dp at constant enthalpy"; @@ -386,26 +407,12 @@ end ThermodynamicState; cp=props[13], w=props[14], phase=if (props[8] > 0 and props[8] < 1) then 2 else 1, - hjt=ders[2], - a=ders[3], - f=ders[4], - kappa=ders[5], - beta=ders[6], - dpdrho_T=ders[7], - d2pdrho2_T=ders[8], - dpdT_rho=ders[9], - drhodT_p=ders[10], - drhodp_T=ders[11], - d2pdT2_rho=ders[12], - d2pdTdrho=ders[13], - dhdT_rho=ders[14], - dhdT_p=ders[15], - dhdrho_T=ders[16], - dhdrho_p=ders[17], - dhdp_T=ders[18], - dhdp_rho=ders[19], - drhodh_p=ders[20], - drhodp_h=ders[21], + q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], + kappa=ders[2], + beta=ders[3], + drhodX_ph=ders[4], + drhodh_p=ders[5], + drhodp_h=ders[6], eta=trns[2], lambda=trns[3]); @@ -534,31 +541,53 @@ end ThermodynamicState; redeclare function extends setBubbleState "set the thermodynamic state on the bubble line" algorithm + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + // + String(bubbleEnthalpy(sat)) + ",X)..."); + // end if; + // state := setState( + // "pq", + // sat.psat, + // 0, + // sat.X, + // phase) ",fluidnames)"; if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(bubbleEnthalpy(sat)) + ",X)..."); + Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," + + String(sat.Tv) + ",X)..."); end if; state := setState( - "pq", - sat.psat, - 0, + "dT", + sat.dl, + sat.Tl, sat.X, - phase) ",fluidnames)"; + phase); + end setBubbleState; redeclare function extends setDewState "set the thermodynamic state on the bubble line" algorithm + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," + // + String(dewEnthalpy(sat)) + ",X)..."); + // end if; + // state := setState( + // "pq", + // sat.psat, + // 1, + // sat.X, + // phase) ",fluidnames)"; if debugmode then - Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - + String(dewEnthalpy(sat)) + ",X)..."); + Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," + + String(sat.Tv) + ",X)..."); end if; state := setState( - "pq", - sat.psat, - 1, + "dT", + sat.dv, + sat.Tv, sat.X, - phase) ",fluidnames)"; + phase); + end setDewState; function setState_pqX "Calculates medium properties from p,q,X" @@ -654,22 +683,75 @@ end ThermodynamicState; phase) ",fluidnames)"; end setState_TsX; - redeclare function extends saturationPressure + function setSat "calculate saturation property record" + extends partialSatREFPROP; + input String statevar; + input Real statevarval; + input Modelica.SIunits.MassFraction X[:] "Mass fractions"; + output SaturationProperties sat "saturation property record"; algorithm - p := getSatProp_REFPROP_check( + assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); + getSatProp_REFPROP( "p", - "T", + statevar, + fluidnames, + satprops, + statevarval, + X, + errormsg); + assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + sat := SaturationProperties( + Tl=satprops[2], + Tv=satprops[3], + pl=satprops[4], + pv=satprops[5], + dl=satprops[6], + dv=satprops[7], + hl=satprops[8], + hv=satprops[9], + sl=satprops[10], + sv=satprops[11], + sigma=satprops[12], + X= satprops[13:13+nX-1]); + end setSat; + + redeclare replaceable function setSat_pX + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "p", + p, + X); + end setSat_pX; + + redeclare replaceable function setSat_TX + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "t", T, X); + end setSat_TX; + + redeclare function extends saturationPressure + algorithm + // this function does not make sense, what pressure do you want? + // use setSat instead end saturationPressure; redeclare function extends saturationTemperature algorithm - T := getSatProp_REFPROP_check( - "T", - "p", - p, - X); + // this function does not make sense, what temperature do you want? + // use setSat instead end saturationTemperature; // redeclare function extends specificEntropy @@ -686,155 +768,38 @@ end ThermodynamicState; redeclare function extends dewEnthalpy "dew curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hv := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 1, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hv :=props[10]; - + hv:=sat.hv; end dewEnthalpy; redeclare function extends dewEntropy "dew curve specific entropy" extends Modelica.Icons.Function; algorithm - sv := getProp_REFPROP_check( - "s", - "pq", - sat.psat, - 1, - sat.X, - 1); + sv:=sat.sv; end dewEntropy; redeclare function extends dewDensity "dew curve specific density" extends Modelica.Icons.Function; - //algorithm - // dv := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 1, - // sat.X, - // 1); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 1, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dv :=props[5]; - + dv:=sat.dv; end dewDensity; redeclare function extends bubbleEnthalpy "boiling curve specific enthalpy" extends Modelica.Icons.Function; - //algorithm - // hl := getProp_REFPROP_check( - // "h", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 0); - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - hl :=props[10]; - + hl:=sat.hl; end bubbleEnthalpy; redeclare function extends bubbleEntropy "boiling curve specific entropy" extends Modelica.Icons.Function; algorithm - sl := getProp_REFPROP_check( - "s", - "pq", - sat.psat, - 0, - sat.X, - 1); + sl:=sat.sl; end bubbleEntropy; redeclare function extends bubbleDensity "boiling curve specific density" extends Modelica.Icons.Function; - //algorithm - // dl := getProp_REFPROP_check( - // "d", - // "pq", - // sat.psat, - // 0, - // sat.X, - // 1); - - extends partialREFPROP; - algorithm - assert(size(sat.X, 1) > 0, "The mass fraction vector must have at least 1 element."); - getProp_REFPROP( - "u", - "pq", - fluidnames, - ders, - trns, - props, - sat.psat, - 0, - sat.X, - 1, - errormsg); - assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); - - dl :=props[5]; - + dl:=sat.dl; end bubbleDensity; redeclare replaceable function extends molarMass @@ -894,7 +859,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_hsX(" + String(h) + "," + String(s) + ",X)"); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "hs", h, @@ -924,7 +889,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_pqX(" + String(p) + "," + String(q) + ",X)"); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "pq", p, @@ -947,7 +912,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_psX(" + String(p) + "," + String(s) + ",X)"); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "ps", p, @@ -978,7 +943,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_pTX(" + String(p) + "," + String(T) + ",X)..."); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "pT", p, @@ -1008,7 +973,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_ThX(" + String(T) + "," + String(h) + ",X)"); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "Th", T, @@ -1038,7 +1003,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running density_TsX(" + String(T) + "," + String(s) + ",X)"); end if; - d := getProp_REFPROP_check( + d := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "d", "Ts", T, @@ -1115,7 +1080,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_dsX(" + String(d) + "," + String(s) + ",X)"); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "ds", d, @@ -1145,7 +1110,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_dTX(" + String(d) + "," + String(T) + ",X)"); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "dT", d, @@ -1175,7 +1140,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_hdX(" + String(h) + "," + String(d) + ",X)"); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "hd", h, @@ -1205,7 +1170,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_hsX(" + String(h) + "," + String(s) + ",X)"); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "hs", h, @@ -1235,7 +1200,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_ThX(" + String(T) + "," + String(h) + ",X)..."); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "Th", T, @@ -1266,7 +1231,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_TqX(" + String(T) + "," + String(q) + ",X)"); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "Tq", T, @@ -1292,7 +1257,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running pressure_TsX(" + String(T) + "," + String(s) + ",X)..."); end if; - p := getProp_REFPROP_check( + p := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "p", "Ts", T, @@ -1329,7 +1294,7 @@ end ThermodynamicState; d) + "," + String(s) + ",X)"); end if; // h :=getProp_REFPROP_check("h", "ds", fluidnames,d,s,X,phase); - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "ds", d, @@ -1363,7 +1328,7 @@ end ThermodynamicState; d) + "," + String(T) + ",X)"); end if; // h :=getProp_REFPROP_check("h", "dT", fluidnames,d,T,X,phase); - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "dT", d, @@ -1396,7 +1361,7 @@ end ThermodynamicState; p) + "," + String(d) + ",X)..."); end if; // h :=getProp_REFPROP_check("h", "pd", fluidnames,p,d,X,phase); - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "pd", p, @@ -1429,7 +1394,7 @@ end ThermodynamicState; p) + "," + String(q) + ",X)"); end if; // h :=getProp_REFPROP_check("h", "pq", fluidnames,p,q,X,phase); - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "pq", p, @@ -1456,7 +1421,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEnthalpy_psX(" + String( p) + "," + String(s) + ",X)..."); end if; - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "ps", p, @@ -1493,7 +1458,7 @@ end ThermodynamicState; p) + "," + String(T) + ",X)..."); end if; // p="+String(p)+",T="+String(T)+", X={"+String(X[1])+","+String(X[2])+"}"); - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "pT", p, @@ -1526,7 +1491,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEnthalpy_TsX(" + String( T) + "," + String(s) + ",X)"); end if; - h := getProp_REFPROP_check( + h := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "h", "Ts", T, @@ -1557,7 +1522,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_dTX(" + String( d) + "," + String(T) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "dT", d, @@ -1587,7 +1552,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_hdX(" + String( h) + "," + String(d) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "hd", h, @@ -1617,7 +1582,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_pdX(" + String( p) + "," + String(d) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "pd", p, @@ -1684,7 +1649,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_pqX(" + String( p) + "," + String(q) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "pq", p, @@ -1705,7 +1670,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_pTX(" + String( p) + "," + String(T) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "pT", p, @@ -1739,7 +1704,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running specificEntropy_ThX(" + String( T) + "," + String(h) + ",X)"); end if; - s := getProp_REFPROP_check( + s := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "s", "Th", T, @@ -1769,7 +1734,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_dsX(" + String(d) + "," + String(s) + ",X)"); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "ds", d, @@ -1799,7 +1764,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_hdX(" + String(h) + "," + String(d) + ",X)"); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "hd", h, @@ -1829,7 +1794,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_hsX(" + String(h) + "," + String(s) + ",X)"); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "hs", h, @@ -1859,7 +1824,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + String(d) + ",X)..."); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "pd", p, @@ -1890,7 +1855,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_pqX(" + String(p) + "," + String(q) + ",X)"); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "pq", p, @@ -1912,7 +1877,7 @@ end ThermodynamicState; Modelica.Utilities.Streams.print("Running temperature_psX(" + String(p) + "," + String(s) + ",X)..."); end if; - T := getProp_REFPROP_check( + T := REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.getProp_REFPROP_check( "T", "ps", p, diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo index 4ca5e00..b2863c8 100644 --- a/Media/NH3_Water.mo +++ b/Media/NH3_Water.mo @@ -1,5 +1,9 @@ within REFPROP2Modelica.Media; package NH3_Water "Ammonia and water mixture by REFPROP library" extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"ammoniaL","water"}); + final substanceNames={"ammoniaL","water"}, + final debugmode=false, + final calcTransport=false, + final calcTwoPhaseNumericalDerivatives=false, + final calcTwoPhasePsuedoAnalyticalDerivatives=true); end NH3_Water; diff --git a/Testers/NH3_Water_setSatModel.mo b/Testers/NH3_Water_setSatModel.mo new file mode 100644 index 0000000..1f2a275 --- /dev/null +++ b/Testers/NH3_Water_setSatModel.mo @@ -0,0 +1,25 @@ +within REFPROP2Modelica.Testers; +model NH3_Water_setSatModel + +package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState dewstate; + Medium.ThermodynamicState bubstate; + + Medium.SaturationProperties sat; + Medium.SaturationProperties sat2; + + Medium.AbsolutePressure p; + Medium.MassFraction X[2]; + +equation + p=50e5; + X={0.5,0.5}; + + sat = Medium.setSat_pX(p,X); + sat2 = Medium.setSat_TX(450,X); + + dewstate = Medium.setDewState(sat); + bubstate = Medium.setBubbleState(sat); + +end NH3_Water_setSatModel; diff --git a/Testers/NH3_Water_setStateModel.mo b/Testers/NH3_Water_setStateModel.mo index db94a0d..abfde2f 100644 --- a/Testers/NH3_Water_setStateModel.mo +++ b/Testers/NH3_Water_setStateModel.mo @@ -20,10 +20,12 @@ Real dddp_hX; Real dddh_pX_num; Real dddp_hX_num; +Real dddX_ph_num; + equation p=50e5; - h=5e5 + time*25e5; - X={0.2,0.8}; + h=3e5 + time*25e5; + X={0.5,0.5}; state = Medium.setState_phX(p,h,X); q = Medium.vapourQuality(state); @@ -36,4 +38,6 @@ equation dddp_hX = Medium.density_derp_h(state); dddp_hX_num = Medium.density(Medium.setState_phX(p+1,h,X))-d; + dddX_ph_num = (Medium.density(Medium.setState_phX(p,h,cat(1,{X[1]+0.0001},{X[2]-0.0001})))-d)/0.0001; + end NH3_Water_setStateModel; diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo index 7a255ab..2870728 100644 --- a/Testers/PropsMixtureNH3H2O.mo +++ b/Testers/PropsMixtureNH3H2O.mo @@ -13,7 +13,8 @@ package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( Modelica.SIunits.AbsolutePressure p; Real q; - Medium.SaturationProperties sat = Medium.setSat_pX(p,X); + Medium.SaturationProperties sat = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.setSat( + p,X); Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index a13a30c..c4b8698 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -9,7 +9,8 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); Modelica.SIunits.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(props.state); Medium.ThermodynamicState state=Medium.setState_phX(props.p,props.h,props.X); - Medium.SaturationProperties sat = Medium.setSat_pX(props.p,props.X); + Medium.SaturationProperties sat = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.setSat( + props.p,props.X); Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); Medium.Density dl = Medium.bubbleDensity(sat); diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index 19722b0..2716197 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -16,6 +16,11 @@ int main(int argc, char* argv[]){ double *ders; double *trns; int DEBUG = 0; + int transport = 0; + int twophaseNumerical = 0; + int twophaseAnalytical = 1; + + double *satprops; int nX=2; // Number of components @@ -27,21 +32,25 @@ int main(int argc, char* argv[]){ char theSepChar[2] = "/"; # endif + + // Allocate space for objects x = (double*) calloc(nX,sizeof(double)); props = (double*) calloc(16+2*nX,sizeof(double)); - ders = (double*) calloc(21,sizeof(double)); + ders = (double*) calloc(9,sizeof(double)); trns = (double*) calloc(3,sizeof(double)); + satprops = (double*) calloc(12+nX,sizeof(double)); + char fluidname[255] = "ammoniaL|water"; - x[0] = 0.2; + x[0] = 0.5; x[1] = 1.0 - x[0]; double p = 50.e5; - double h = 20.0e5; - double dh = 0e6; + double h = 3.0e5; + double dh = 2.5e6; - int N = 2; // steps in enthalpy + int N = 500; // steps in enthalpy int M = 1; // repetitions double res = 0.0; @@ -49,7 +58,7 @@ int main(int argc, char* argv[]){ // Format the output properly char buffer [100]; - int limit = 100; + int limit = 105; std::ostringstream out; out << std::endl; @@ -60,13 +69,31 @@ int main(int argc, char* argv[]){ for (int i = 0; i < M; i++) { for (int count = 0; count < N; count++) { h_in = h + dh * count / (N - 1); - res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG); + + res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG, transport, twophaseNumerical, twophaseAnalytical); + if (N*M +#include +#include +#include +#include +#include +#include +#include "cpp_wrapped.h" +//#include "../src/refprop_library.h" +#include + + +int main(int argc, char* argv[]){ + + // Allocate space for objects + int nX=2; // Number of components + double* x; + x = (double*) calloc(nX,sizeof(double)); + + char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; + char theSepChar[2] = "\\"; + x[0] = 0.5; + x[1] = 1.0 - x[0]; + double p = 50.e5; + double h = 3.0e5; + + char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], + herr[errormessagelength+1],hfmix[refpropcharlength+1]; + double xmol[ncmax],xliq[ncmax],xvap[ncmax]; + double wm; + long i=0, ierr=0; + double q,e,s,cv,cp,w,tt,dd,dl,dv; + + strcpy(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"ammoniaL.fld|"); + strcat(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"water.fld"); + + strcpy(hfmix,thepathChar); + strcat(hfmix,theSepChar); + strcat(hfmix,"fluids"); + strcat(hfmix,theSepChar); + strcat(hfmix,"HMX.BNC"); + + strcpy(hrf,"DEF"); + strcpy(herr,"Ok"); + + i = nX; + + HINSTANCE RefpropdllInstance; + RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\refprop.dll"); + + TDFLSHdll = (TDFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + PHFLSHdll = (PHFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + SETUPdll = (SETUPdll_POINTER) GetProcAddress(RefpropdllInstance,"SETUPdll"); + WMOLdll = (WMOLdll_POINTER) GetProcAddress(RefpropdllInstance,"WMOLdll"); + XMOLEdll = (XMOLEdll_POINTER) GetProcAddress(RefpropdllInstance,"XMOLEdll"); + + + + /* + //...Call SETUP to initialize the program + //long ,char*,char*,char*,long ,char*,long ,long ,long ,long + SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); + + if (ierr != 0) printf("%s\n",herr); + //WMOLdll(x,wm); + XMOLEdll(x,xmol,wm); + + double hmol = h*wm/1000.0; + double pkpa = p/1000.0; + + PHFLSHdll(pkpa,hmol,xmol,tt,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + + printf("T = %f\n",tt); + printf("D = %f\n",dd); + printf("xmole = %f,%f\n",xmol[0],xmol[1]); + + double pnew,hnew; + TDFLSHdll(tt,dd,xmol,pnew,dl,dv,xliq,xvap,q,e,hnew,s,cv,cp,w,ierr,herr,errormessagelength); +// ( t, D, z, p, Dl,Dv, x, y, q,e,h,s,cv,cp,w,ierr,herr) + printf("p = %f\n",pnew); + printf("h = %f\n",hnew/wm*1000); + + */ + + + // new fluid + + strcpy(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"methane.fld|"); + strcat(hf,thepathChar); + strcat(hf,theSepChar); + strcat(hf,"fluids"); + strcat(hf,theSepChar); + strcat(hf,"ethane.fld"); + + //...Call SETUP to initialize the program + //long ,char*,char*,char*,long ,char*,long ,long ,long ,long + SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); + printf("ierr = %ld\n",ierr); + + + xmol[0]=0.5; + xmol[1]=0.5; + tt=250; + dd=15; //mol/dm^3 + + double h1,h2,p1,p2,dpdx1_tv,dhdx1_tv; + double xmolnew[ncmax]; + double dx=1e-7; + xmolnew[0]=0.5+dx; + xmolnew[1]=0.5; + + TDFLSHdll(tt,dd,xmol,p1,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); + printf("ierr = %ld\n",ierr); + printf("p1 = %f\n",p1); + printf("h1 = %f\n",h1); + printf("xmole1 = %1.10f,%1.10f\n",xmol[0],xmol[1]); + + TDFLSHdll(tt,dd,xmolnew,p2,dl,dv,xliq,xvap,q,e,h2,s,cv,cp,w,ierr,herr,errormessagelength); + printf("ierr = %ld\n",ierr); + printf("p2 = %f\n",p2); + printf("h2 = %f\n",h2); + printf("xmole2 = %1.10f,%1.10f\n",xmolnew[0],xmolnew[1]); + + dpdx1_tv = (p2-p1)/dx; + dhdx1_tv = (h2-h1)/dx; + printf("dpdx1_tv = %f\n",dpdx1_tv); + printf("dhdx1_tv = %f\n",dhdx1_tv); + + double dpdx2_tv,dhdx2_tv; + xmolnew[0]=0.5; + xmolnew[1]=0.5+dx; + + TDFLSHdll(tt,dd,xmol,p1,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); + printf("ierr = %ld\n",ierr); + printf("p1 = %f\n",p1); + printf("h1 = %f\n",h1); + printf("xmole1 = %1.10f,%1.10f\n",xmol[0],xmol[1]); + + TDFLSHdll(tt,dd,xmolnew,p2,dl,dv,xliq,xvap,q,e,h2,s,cv,cp,w,ierr,herr,errormessagelength); + printf("ierr = %ld\n",ierr); + printf("p2 = %f\n",p2); + printf("h2 = %f\n",h2); + printf("xmole2 = %1.10f,%1.10f\n",xmolnew[0],xmolnew[1]); + + dpdx2_tv = (p2-p1)/dx; + dhdx2_tv = (h2-h1)/dx; + printf("dpdx2_tv = %f\n",dpdx2_tv); + printf("dhdx2_tv = %f\n",dhdx2_tv); + + return 0; +} diff --git a/_wrapper/src/refprop_library.h b/_wrapper/src/refprop_library.h index 5231ae8..77b1495 100644 --- a/_wrapper/src/refprop_library.h +++ b/_wrapper/src/refprop_library.h @@ -130,6 +130,9 @@ # define WMOLdll WMOLdll # define XMASSdll XMASSdll # define XMOLEdll XMOLEdll + + + #elif defined(__ISLINUX__) // defined(__ISWINDOWS__) // Define compiler specific calling conventions // for the shared library. @@ -781,6 +784,8 @@ extern "C" { typedef WMOLdll_TYPE * WMOLdll_POINTER; typedef XMASSdll_TYPE * XMASSdll_POINTER; typedef XMOLEdll_TYPE * XMOLEdll_POINTER; + + #if defined(__cplusplus) } // extern "C" #endif // __cplusplus diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index b7f127d..01c21a3 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -94,6 +94,10 @@ static const double noValue = -1e+10; // double qualityFactor = noValue; // qmass = qmole * mw_vap / mw bool debug; // set the debug flag +bool calcTrans; +bool calcTwoPhaseNumDers; +bool calcTwoPhasePsuedoAnalDers; + //long lerr; // Error return mechanism double dhelp = noValue; @@ -102,6 +106,10 @@ double dhelp = noValue; * Properties for saturation states. "dew" refers to the dew point and * "bub" describes the bubble point. */ + +double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat,dxmollsat[ncmax],dxmolvsat[ncmax],dplsat,dhlsat,dslsat,dcvlsat,dcplsat,dwlsat,dpvsat,dhvsat,dsvsat,dcvvsat,dcpvsat,dwvsat,dtlsat,dtvsat; + +// TODO hmm it does not seem that these are ever used? double dtdew, dpdew, ddldew, ddvdew, dtbub, dpbub, ddlbub, ddvbub; int flushSaturation() { dtdew=noValue; @@ -135,7 +143,9 @@ double deta, dtcx; //double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; -double ddddp_h, ddddh_p; +//double dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; + +double ddddp_h, ddddh_p, ddddX_ph; int flushProperties(){ dt=noValue; @@ -155,32 +165,17 @@ int flushProperties(){ dw=noValue; dwliq=noValue; dwvap=noValue; + dhjt=noValue; dZ[0]=noValue; dA=noValue; dG=noValue; dxkappa=noValue; dbeta=noValue; -// ddpdd=noValue; -// dd2pdd2=noValue; -// ddpdt=noValue; -// ddddt=noValue; -// ddddp=noValue; -// dd2pdt2=noValue; -// dd2pdtd=noValue; -// ddhdt=noValue; -// df=noValue; This is not used deta=noValue; dtcx=noValue; -// dstn=noValue; This is not used - -// ddhdt_d=noValue; -// ddhdt_p=noValue; -// ddhdd_t=noValue; -// ddhdd_p=noValue; -// ddhdp_t=noValue; -// ddhdp_d=noValue; + ddddX_ph=noValue; ddddp_h=noValue; ddddh_p=noValue; @@ -1012,7 +1007,7 @@ double getDV_modelica(){ double getQ_modelica(){ if (lnc>1 && abs(dqmol)<990) { // maintain special values if (dwvap==noValue) WMOLdll(dxmolv,dwvap); - return dqmol*dwvap/dwm; + return dqmol*dwvap/dwm; // TODO can you show a case where this function is called more than once? } else { return dqmol; } @@ -1124,8 +1119,12 @@ double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] } */ -// Analytical derivatives +// Derivatives // Derivative of density with respect to enthalpy at constant pressure +double get_dddX_ph_modelica(){ + if (dwvap==noValue) WMOLdll(dxmolv,dwvap); + return ddddX_ph*dwm*dwm/dwvap; // [mol/l * mol/molvap] * g/mol * g/mol * molvap/gvap * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gvap +} double get_dddh_p_modelica(){ return ddddh_p*dwm*dwm/1000.; // [mol/l * mol/J] * g/mol * g/mol * 1e-3kg/g * 1e-3kg/g / 1e-3 m3/L = kg/m3 * kg/J } @@ -1351,26 +1350,11 @@ int updateDers(double *ders, long lerr){ */ // TODO - I have reduced the variables thrown back.. Why us jtc, a, g derivatives here? ders[0] = lerr;//error code - ders[1] = getHJT_modelica(); // isenthalpic Joule-Thompson coefficient [K/Pa] - ders[2] = getA_modelica(); // Helmholtz energy [J/kg] - ders[3] = getG_modelica(); // Gibbs free energy [J/kg] - ders[4] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] - ders[5] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] - ders[6] = 1; // derivative dP/drho [Pa-m3/kg] - ders[7] = 1; // derivative d^2P/drho^2 [Pa-m6/kg2] - ders[8] = 1; // derivative dP/dT [Pa/K] - ders[9] = 1; // derivative drho/dT [kg/(m3-K)] - ders[10] = 1; // derivative drho/dP [kg/(m3-kPa)] - ders[11] = 1; // derivative d2P/dT2 [Pa/K2] - ders[12] = 1; // derivative d2P/dTd(rho) [J/kg-K] - ders[13] = 1; // dH/dT at constant density [J/(kg-K)] - ders[14] = 1; // dH/dT at constant pressure [J/(kg-K)] - ders[15] = 1; // dH/drho at constant temperature [(J/kg) / (kg/m3)] - ders[16] = 1; // dH/drho at constant pressure [(J/kg) / (kg/m3)] - ders[17] = 1; // dH/dP at constant temperature [J/(kg-Pa)] - ders[18] = 1; // dH/dP at constant density [J/(kg-Pa)] - ders[19] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] - ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + ders[1] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[2] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[3] = get_dddX_ph_modelica(); // dH/dP at constant density [J/(kg-Pa)] + ders[4] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] + ders[5] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] return 0; } @@ -1392,15 +1376,64 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + // analytical derivatives ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; ddddh_p = -dbeta*dd/dCp; - + + // numerical derivative for ddddzi + double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz,dpdz_td,dhdz_td; + + dpdT_zv = dbeta/dxkappa; + dpdv_Tz= -dd/dxkappa; + dhdT_vz = dCv+dbeta/(dd*dxkappa); + dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); + +// printf("dxmol,%f,%f\n",dxmol[0],dxmol[1]); +// printf("dpdT_zv,%f\n",dpdT_zv); +// printf("dpdv_Tz,%f\n",dpdv_Tz); +// printf("dhdT_vz,%f\n",dhdT_vz); +// printf("dhdT_vz,%f\n",dhdv_Tz); + + double dxmolnew[ncmax]; + double pnew,hnew; + double dvdz_ph; + + dxmolnew[0]=dxmol[0]+0.001; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const + dxmolnew[1]=dxmol[1]-0.001; // TODO, check refprop if it recomputes concentration + PRESSdll (dt,dd,dxmolnew,pnew); // this function need not sum(z)=1, or? --- it does + ENTHALdll (dt,dd,dxmolnew,hnew); // this function need not sum(z)=1, or? --- it does + dpdz_td = (pnew-dp)/0.001; + dhdz_td = (hnew-dh)/0.001; + +// printf("xmol,%f,%f\n",dxmolnew[0],dxmolnew[1]); +// printf("d,%f\n",dd); +// printf("t,%f\n",dt); +// printf("p,%f\n",dp); +// printf("pnew,%f\n",pnew); +// printf("h,%f\n",dh); +// printf("hnew,%f\n",hnew); +// printf("dpdz_td,%f\n",dpdz_td); +// printf("dhdz_td,%f\n",dhdz_td); + + // expression from jacobian matrix transformation + dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); +// printf("dvdz_ph,%f\n",dvdz_ph); + ddddX_ph = -dd*dd*dvdz_ph; // this is still in refprop units, so X is molvap/mol.. +// printf("ddddX_ph ,%f\n",ddddX_ph); + + } else { // two-phase region, get derivative of density // These are not computed in two-phase! dxkappa=noValue; dbeta=noValue; + if (calcTwoPhasePsuedoAnalDers) { + if (debug) printf ("Using Analytical twophase derivatives\n"); + +// // TODO the below analytical derivs are wrong since saturated liquid and vapor concentrations change along evaporation.. + + /* j--phase flag: 1 = input x is liquid composition (bubble point) 2 = input x is vapor composition (dew point) 3 = input x is liquid composition (freezing point) @@ -1413,8 +1446,6 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ SATPdll(dp,dxmol,kph2,dt_v,spare3,ddv_v,spare2,spare1,lerr,errormsg,errormessagelength); THERM2dll(dt_v, ddv_v, dxmol, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); - - //compute saturated liquid state long kph1 = 1; double dt_l,ddl_l,dCv_l,dCp_l,dwm_l,dxkappa_l,dbeta_l,h_l,s_l; @@ -1432,15 +1463,259 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ dhdpV = 1/ddv_v*(1-dbeta_v*dt_v)+dCp_v*dTdp_clasius; dvdpL = dbeta_l*1/ddl_l*dTdp_clasius-dxkappa_l*1/ddl_l; dvdpV = dbeta_v*1/ddv_v*dTdp_clasius-dxkappa_v*1/ddv_v; - - //TODO - Everything so far is refprop units, but for some reason the quality below must be on mass basic? - double dqmoltmp; - dqmoltmp = dqmol*dwvap/dwm; - dxdp_h = (dhdpL + dqmoltmp * (dhdpV-dhdpL))/(h_l-h_v); - dvdp_h = dvdpL+dxdp_h*(1/ddv_v-1/ddl_l)+dqmoltmp*(dvdpV-dvdpL); + dxdp_h = (dhdpL + dqmol * (dhdpV-dhdpL))/(h_l-h_v); + dvdp_h = dvdpL+dxdp_h*(1/ddv_v-1/ddl_l)+dqmol*(dvdpV-dvdpL); ddddp_h = -dd*dd*dvdp_h; + + // numerical derivative for ddddzi, that ensures xmol is between 0 and 1 + double HA,HB,smooth,DX,dxmolnew[ncmax],dlow,dhigh; + HA = 0.925*(h_v-h_l)+h_l; + HB = 0.975*(h_v-h_l)+h_l; + + /* + // using PHFLSH to get numerical derivative ddddzi + DX=0.005; + if (dh < HA) { + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dlow-dd)/DX; + } else if (dh > HB) { + DX=-DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dhigh-dd)/DX; + } else { + smooth=(dh-HA)/(HB-HA); + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); + } + */ + + // Using TPFLSH to get numerical derivative ddddzi + double dhdT_pX, dddT_pX,hlow,hhigh,dddX_pT,dhdX_pT; + + dhdT_pX = (h_v - h_l)/(dt_v-dt_l); + //dvdT_p = (1/ddv_v - 1/ddl_l)/(dt_v-dt_l); + dddT_pX = -dd*dd*(1/ddv_v - 1/ddl_l)/(dt_v-dt_l); + + DX=0.0025; + if (dh < HA) { + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(DX); + dhdX_pT = (hlow-dh)/(DX); + } else if (dh > HB) { + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dhigh-dd)/(DX); + dhdX_pT = (hhigh-dh)/(DX); + } else { // something smooth + smooth=(dh-HA)/(HB-HA); + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); + dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); + } + ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + + + } else if (calcTwoPhaseNumDers) { + if (debug) printf ("Using Numerical two phase derivatives\n"); + + // in the following HA and HB are points in two-phase, where the numerical derivative changes "the sign of change", e.g dT into -dT smoothly (linearly) + + double HA,HB,dxmolnew[ncmax],Tnew,pnew,dlow,dhigh,hlow,hhigh,h_l,h_v; + //double ddq,ddl_l,ddv_v,ddx[ncmax],ddy[ncmax]; + + ENTHALdll (dt,ddl,dxmoll,h_l); + ENTHALdll (dt,ddv,dxmolv,h_v); + HA = 0.025*(h_v-h_l)+h_l; + HB = 0.075*(h_v-h_l)+h_l; + + //printf("hl = %f", h_l); + //printf("hv = %f", h_v); + + double DT,DP,DX,smooth,dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; + + DT=0.5; + DP=-25; + DX=0.002; + + if (dh < HA) { + // DT + //DT=DT; + Tnew= dt+DT; + //this function does not work? + //(t,p,z,Dl,Dv,x,y,q,ierr,herr) + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(DT); + dhdT_pX = (hlow-dh)/(DT); + // DP + //DP=DP; + pnew = dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(DP); + dhdP_TX = (hlow-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(DX); + dhdX_pT = (hlow-dh)/(DX); + } else if (dh > HB) { + // DT + DT = -DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dhigh-dd)/(DT); + dhdT_pX = (hhigh-dh)/(DT); + // DP + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dhigh-dd)/(DP); + dhdP_TX = (hhigh-dh)/(DP); + // DX + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dhigh-dd)/(DX); + dhdX_pT = (hhigh-dh)/(DX); + } else { // something smooth + smooth=(dh-HA)/(HB-HA); + // DT + //DT = DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DT=-DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(-DT)*(1-smooth) + smooth*(dhigh-dd)/(DT); + dhdT_pX = (hlow-dh)/(-DT)*(1-smooth) + smooth*(hhigh-dh)/(DT); + // DP + //DP = DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(-DP)*(1-smooth) + smooth*(dhigh-dd)/(DP); + dhdP_TX = (hlow-dh)/(-DP)*(1-smooth) + smooth*(hhigh-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); + dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); + } + + ddddh_p = dddT_pX/dhdT_pX; + ddddp_h = (dddP_TX*dhdT_pX-dhdP_TX*dddT_pX)/dhdT_pX; + ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + + } else { + printf("Both partial derivative calculation flags cannot be true.."); + } + /* printf("dqmol %f\n", dqmol); if (dwvap==noValue) @@ -1595,7 +1870,7 @@ int updateProps(double *props, long lerr){ } -double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +double props_REFPROP(char* what, char* statevars_in, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport, int calcTwoPhaseNumericalDerivatives, int calcTwoPhasePsuedoAnalyticalDerivatives){ /*Calculates thermodynamic properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) INPUT: what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function @@ -1622,6 +1897,10 @@ OUTPUT // DEBUGMODE = 1; if (DEBUGMODE) debug = true; + if (calcTransport) calcTrans=true; + if (calcTwoPhaseNumericalDerivatives) calcTwoPhaseNumDers=true; + if (calcTwoPhasePsuedoAnalyticalDerivatives) calcTwoPhasePsuedoAnalDers=true; + std::string out = std::string(what).substr(0,1); std::string in1 = std::string(statevars_in).substr(0,1); std::string in2 = std::string(statevars_in).substr(1,1); @@ -1724,7 +2003,7 @@ OUTPUT } else { // We have calculated it before. if (valueExists) { if (debug) printf("Working with old state, returning value for %s: %f.\n",out.c_str(),result); - updateProps(props, lerr); + updateProps(props, lerr); // TODO Why only props? Are ders,trns, and props not already known? return result; } } @@ -1973,15 +2252,14 @@ OUTPUT updateProps(props, lerr); - // TODO - - int outVal = ders_REFPROP(ders,errormsg,debug); - if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); - /* - outVal = trns_REFPROP(trns,errormsg,debug); - if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); - */ - + if (calcTwoPhaseNumDers || calcTwoPhasePsuedoAnalDers) { + int outVal = ders_REFPROP(ders,errormsg,debug); + if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + } + if (calcTrans) { + int outVal = trns_REFPROP(trns,errormsg,debug); + if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); + } if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); return getP_modelica(); @@ -2025,7 +2303,7 @@ OUTPUT //--------------------------------------------------------------------------- -double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ /*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) INPUT: what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function @@ -2046,6 +2324,8 @@ OUTPUT // DEBUGMODE = 1; if (DEBUGMODE) debug = true; + if (calcTransport) calcTrans=true; + std::string out = std::string(what).substr(0,1); std::string in1 = std::string(statevar_in).substr(0,1); std::string fluids = std::string(fluidnames); @@ -2057,7 +2337,7 @@ OUTPUT * Afterwards, the fluids have been processed and the constants might * have been flushed. */ - if (debug) printf("\nStarting function props_REFPROP to calculate %s.\n", out.c_str()); + if (debug) printf("\nStarting function satprops_REFPROP to calculate %s.\n", out.c_str()); if (setFluids(rPath,fluids,errormsg) != OK) { printf("Error initialising REFPROP: \"%s\"\n", errormsg); @@ -2073,6 +2353,8 @@ OUTPUT bool knownState = false; // dummies to force recalculation bool valueExists = false; + +// TODO - why do we want to flush properties for the setState functions here when setsat is called? if (!knownState) { if (lnc>1) flushConstants(); else flushProperties(); @@ -2093,40 +2375,60 @@ OUTPUT // Convert mass-based composition to mole fractions and set molecular weight. double* dxkg; dxkg = x; - XMOLEdll(dxkg,dxmol,dwm); - // dwm = dwm / 1000; // from g/mol to kg/mol + XMOLEdll(dxkg,dxmolsat,dwmsat); + // dwm = dwm / 1000; // from g/mol to kg/mol //keep refprop units.. // loop through possible inputs if ( strCompare(in1, "p") ) { - dp = getP_refprop(statevarval); + dpsat = getP_refprop(statevarval); } else if ( strCompare(in1, "t") ) { - dt = getT_refprop(statevarval); - } else if ( strCompare(in1, "d") ) { + dtsat = getT_refprop(statevarval); + } + /* else if ( strCompare(in1, "d") ) { dd = getD_refprop(statevarval); - } else { + } */ + else { lerr = 2; sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); return lerr; } if (debug) printf("\nstatevar %s checked\n",in1.c_str()); - long j=2; + long j; /* j--phase flag: 1 = input x is liquid composition (bubble point) 2 = input x is vapor composition (dew point) 3 = input x is liquid composition (freezing point) 4 = input x is vapor composition (sublimation point) */ - long kph = -1; + //long kph = -1; /* kph--flag specifying desired root for multi-valued inputs has meaning only for water at temperatures close to its triple point -1 = return middle root (between 0 and 4 C) 1 = return highest temperature root (above 4 C) 3 = return lowest temperature root (along freezing line) */ + + double spare1,spare2,spare3,spare4,spare10[ncmax]; + if (lerr==0) { if ( strCompare(in1, "t") ) { - SATTdll(dt,dxmol,j,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + j=1; + SATTdll(dtsat,dxmolsat,j,dplsat,ddlsat,spare1,dxmollsat,spare10,lerr,errormsg,errormessagelength); + THERMdll (dtsat,ddlsat,dxmollsat,spare1,spare2,dhlsat,dslsat,dcvlsat,dcplsat,spare3,spare4); + j=2; + SATTdll(dtsat,dxmolsat,j,dpvsat,spare1,ddvsat,spare10,dxmolvsat,lerr,errormsg,errormessagelength); + THERMdll (dtsat,ddvsat,dxmolvsat,spare1,spare2,dhvsat,dsvsat,dcvvsat,dcpvsat,spare3,spare4); + dtlsat=dtsat; + dtvsat=dtsat; + //THERM (t, rho, x, p, e, h, s, cv, cp, w, hjt) } else if ( strCompare(in1, "p") ) { - SATPdll(dp,dxmol,j,dt,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + j=1; + SATPdll(dpsat,dxmolsat,j,dtlsat,ddlsat,spare1,dxmollsat,spare10,lerr,errormsg,errormessagelength); + THERMdll (dtlsat,ddlsat,dxmollsat,dplsat,spare2,dhlsat,dslsat,dcvlsat,dcplsat,spare3,spare4); + j=2; + SATPdll(dpsat,dxmolsat,j,dtvsat,spare1,ddvsat,spare10,dxmolvsat,lerr,errormsg,errormessagelength); + THERMdll (dtvsat,ddvsat,dxmolvsat,dpvsat,spare2,dhvsat,dsvsat,dcvvsat,dcpvsat,spare3,spare4); + //dplsat=dpsat; + //dpvsat=dpsat; switch(lerr){ case 2: strcpy(errormsg,"P < Ptp"); @@ -2136,7 +2438,9 @@ OUTPUT break; } //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); - } else if ( strCompare(in1, "d") ) { + } + /* + else if ( strCompare(in1, "d") ) { SATDdll(dd,dxmol,j,kph,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); switch(lerr){ case 2: @@ -2144,6 +2448,7 @@ OUTPUT break; } } + */ } switch(lerr){ @@ -2233,46 +2538,50 @@ OUTPUT break; } - //ASSIGN VALUES TO RETURN ARRAY - props[0] = lerr;//error code - props[1] = getP_modelica(); //pressure in kPa->Pa - props[2] = getT_modelica(); //Temperature in K - props[3] = getWM_modelica(); //molecular weight - props[4] = getD_modelica(); //density - props[5] = getDL_modelica(); //density of liquid phase - props[6] = getDV_modelica(); //density of liquid phase - props[7] = 0; - props[8] = 0; //inner energy - props[9] = 0; //specific enthalpy - props[10] = 0; //specific entropy - props[11] = 0; - props[12] = 0; - props[13] = 0; //speed of sound - props[14] = getWML_modelica(); - props[15] = getWMV_modelica(); - double dxlkg[ncmax], dxvkg[ncmax]; + double dsigma=0; //TODO get surface tension.. using flag and so on.. - XMASSdll(dxmoll,dxlkg,dwliq); - XMASSdll(dxmolv,dxvkg,dwvap); + double dxlkg[ncmax], dxvkg[ncmax]; + XMASSdll(dxmollsat,dxlkg,dwlsat); + XMASSdll(dxmolvsat,dxvkg,dwvsat); + //ASSIGN VALUES TO RETURN ARRAY + satprops[0] = lerr;//error code + satprops[1] = dtlsat; //Temperature in K + satprops[2] = dtvsat; //Temperature in K + satprops[3] = dplsat*1000; //pressure in kPa->Pa + satprops[4] = dpvsat*1000; //pressure in kPa->Pa + satprops[5] = ddlsat*dwlsat; //density of liquid phase mol/L ->g/L (kg/m3) + satprops[6] = ddvsat*dwvsat; //density of vapor phase mol/L ->g/L (kg/m3) + satprops[7] = dhlsat/dwlsat*1000; //enthalpy of liquid J/mol -> J/g e-3 -> J/kg + satprops[8] = dhvsat/dwvsat*1000; //enthalpy of vapor J/mol -> J/g e-3 -> J/kg + satprops[9] = dslsat/dwlsat*1000; //entropy of liquid J/molK -> J/gK e-3 -> J/kgK + satprops[10] = dsvsat/dwvsat*1000; //entropy of vapor J/molK -> J/gK e-3 -> J/kgK + satprops[11] = dsigma; //surface tension + +// satprops[12] = dwlsat/1000; //molecular weight g/mol -> kg/mol +// satprops[13] = dwvsat/1000; //molecular weight g/mol -> kg/mol for (int ii=0;ii Date: Tue, 17 Dec 2013 14:46:26 +0100 Subject: [PATCH 48/57] I added surface tension computation for setSat_TX For setSat_pX I added an additional temperature input, if zero then sigma is zero, otherwise computed.. --- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 14 +++++++++++++- Media/NH3_Water.mo | 2 +- Testers/NH3_Water_setSatModel.mo | 2 +- _wrapper/cpptest/cpp_wrapped.cpp | 10 +++++----- _wrapper/cpptest/cpp_wrapped.h | 10 +++++----- _wrapper/src/BuildLIB-VS2010.bat | 4 ++++ _wrapper/src/refprop_wrapper.cpp | 18 +++++++++++++++--- _wrapper/src/refprop_wrapper.h | 2 +- 8 files changed, 45 insertions(+), 17 deletions(-) diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index ef71955..6f89dca 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -147,6 +147,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String fluidnames; input Real[:] satprops; input Real statevarval; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; input String errormsg; output Real val; @@ -157,6 +159,7 @@ partial package REFPROPMixtureTwoPhaseMedium fluidnames, satprops, statevarval, + Tsurft, X, REFPROP_PATH, errormsg, @@ -172,6 +175,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String statevar; // input String fluidnames; input Real statevarval; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; output Real val; algorithm @@ -182,6 +187,7 @@ partial package REFPROPMixtureTwoPhaseMedium fluidnames, satprops, statevarval, + Tsurft, X, errormsg) "just passing through"; //Error string decoding in wrapper-c-function @@ -688,6 +694,8 @@ end ThermodynamicState; input String statevar; input Real statevarval; input Modelica.SIunits.MassFraction X[:] "Mass fractions"; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; output SaturationProperties sat "saturation property record"; algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); @@ -697,6 +705,7 @@ end ThermodynamicState; fluidnames, satprops, statevarval, + Tsurft, X, errormsg); assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); @@ -721,12 +730,15 @@ end ThermodynamicState; extends Modelica.Icons.Function; input AbsolutePressure p "pressure"; input MassFraction X[nX] "Mass fractions"; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; output SaturationProperties sat "saturation property record"; algorithm sat := setSat( "p", p, - X); + X, + Tsurft); end setSat_pX; redeclare replaceable function setSat_TX diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo index b2863c8..913b096 100644 --- a/Media/NH3_Water.mo +++ b/Media/NH3_Water.mo @@ -3,7 +3,7 @@ package NH3_Water "Ammonia and water mixture by REFPROP library" extends Interfaces.REFPROPMixtureTwoPhaseMedium( final substanceNames={"ammoniaL","water"}, final debugmode=false, - final calcTransport=false, + final calcTransport=true, final calcTwoPhaseNumericalDerivatives=false, final calcTwoPhasePsuedoAnalyticalDerivatives=true); end NH3_Water; diff --git a/Testers/NH3_Water_setSatModel.mo b/Testers/NH3_Water_setSatModel.mo index 1f2a275..6365c82 100644 --- a/Testers/NH3_Water_setSatModel.mo +++ b/Testers/NH3_Water_setSatModel.mo @@ -16,7 +16,7 @@ equation p=50e5; X={0.5,0.5}; - sat = Medium.setSat_pX(p,X); + sat = Medium.setSat_pX(p,X,450); sat2 = Medium.setSat_TX(450,X); dewstate = Medium.setDewState(sat); diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index 2716197..da7baf8 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -48,9 +48,9 @@ int main(int argc, char* argv[]){ double p = 50.e5; double h = 3.0e5; - double dh = 2.5e6; + double dh = 0;//2.5e6; - int N = 500; // steps in enthalpy + int N = 2; // steps in enthalpy int M = 1; // repetitions double res = 0.0; @@ -78,21 +78,21 @@ int main(int argc, char* argv[]){ sprintf (buffer, "T = %8.4f [K]",props[2]); out << buffer << std::endl; - /* res = satprops_REFPROP((char*)"p", (char*)"t", fluidname, satprops, props[2], x, thepathChar, errormsg, DEBUG, transport); + res = satprops_REFPROP((char*)"p", (char*)"t", fluidname, satprops, props[2], 0, x, thepathChar, errormsg, DEBUG, transport); sprintf (buffer, "Pl(T) = %8.4f [Pa]",satprops[3]); out << buffer << std::endl; sprintf (buffer, "Pv(T) = %8.4f [Pa]",satprops[4]); out << buffer << std::endl; - res = satprops_REFPROP((char*)"t", (char*)"p", fluidname, satprops, p, x, thepathChar, errormsg, DEBUG, transport); + res = satprops_REFPROP((char*)"t", (char*)"p", fluidname, satprops, p, 0, x, thepathChar, errormsg, DEBUG, transport); sprintf (buffer, "Tl(p) = %8.4f [K]",satprops[1]); out << buffer << std::endl; sprintf (buffer, "Tv(p) = %8.4f [K]",satprops[2]); out << buffer << std::endl; - */ + sprintf (buffer, "Ders = %8.0f , %8.12f , %8.1f , %8.1f , %8.12f , %8.8f , %8.1f , %8.2f , %8.2f , %8.9f , %8.9f , %8.9f, %8.1f",ders[0],ders[1],ders[2],ders[3],ders[4],ders[5],ders[6],ders[7],ders[8],ders[18],ders[19],ders[20],ders[6]); out << buffer << std::endl << std::endl; } diff --git a/_wrapper/cpptest/cpp_wrapped.h b/_wrapper/cpptest/cpp_wrapped.h index 9370fbb..c71b2c9 100644 --- a/_wrapper/cpptest/cpp_wrapped.h +++ b/_wrapper/cpptest/cpp_wrapped.h @@ -56,10 +56,10 @@ typedef void (CALLCONV *TDFLSHdll_POINTER)(double &,double &,double *,double &,d //WMOLdll_POINTER WMOLdll; //PHFLSHdll_POINTER PHFLSHdll; -SETUPdll_POINTER SETUPdll; -WMOLdll_POINTER WMOLdll; -XMOLEdll_POINTER XMOLEdll; -PHFLSHdll_POINTER PHFLSHdll; -TDFLSHdll_POINTER TDFLSHdll; +extern SETUPdll_POINTER SETUPdll; +extern WMOLdll_POINTER WMOLdll; +extern XMOLEdll_POINTER XMOLEdll; +extern PHFLSHdll_POINTER PHFLSHdll; +extern TDFLSHdll_POINTER TDFLSHdll; #endif diff --git a/_wrapper/src/BuildLIB-VS2010.bat b/_wrapper/src/BuildLIB-VS2010.bat index 22910d8..b79d84b 100644 --- a/_wrapper/src/BuildLIB-VS2010.bat +++ b/_wrapper/src/BuildLIB-VS2010.bat @@ -8,3 +8,7 @@ cl /c /Ox /fp:fast /MD /EHsc refprop_wrapper.cpp lib refprop_wrapper.obj erase *.obj + +copy refprop_wrapper.lib "C:\Program Files (x86)\Dymola 2013\bin\lib\" +copy refprop_wrapper.h "C:\Program Files (x86)\Dymola 2013\Source\" +copy refprop_library.h "C:\Program Files (x86)\Dymola 2013\Source\" \ No newline at end of file diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 01c21a3..1652c98 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -2303,7 +2303,7 @@ OUTPUT //--------------------------------------------------------------------------- -double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double Tsurft, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ /*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) INPUT: what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function @@ -2324,7 +2324,6 @@ OUTPUT // DEBUGMODE = 1; if (DEBUGMODE) debug = true; - if (calcTransport) calcTrans=true; std::string out = std::string(what).substr(0,1); std::string in1 = std::string(statevar_in).substr(0,1); @@ -2539,7 +2538,20 @@ OUTPUT } - double dsigma=0; //TODO get surface tension.. using flag and so on.. + + + double dsigma; + + if (calcTransport) { + if ( strCompare(in1, "t") ) { + SURTENdll (dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,dsigma,lerr,errormsg,errormessagelength); + } else if ( strCompare(in1, "p") ) { + SURFTdll (Tsurft,ddlsat,dxmollsat,dsigma,lerr,errormsg,errormessagelength); + } + } else { + dsigma =0; + } + double dxlkg[ncmax], dxvkg[ncmax]; XMASSdll(dxmollsat,dxlkg,dwlsat); diff --git a/_wrapper/src/refprop_wrapper.h b/_wrapper/src/refprop_wrapper.h index 06f4d6f..a3ed490 100644 --- a/_wrapper/src/refprop_wrapper.h +++ b/_wrapper/src/refprop_wrapper.h @@ -43,7 +43,7 @@ extern "C" { #endif // __cplusplus EXPCONV double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport, int calcTwoPhaseNumericalDerivatives, int calcTwoPhasePsuedoAnalyticalDerivatives); //declaration; - EXPCONV double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *ders, double *trns, double *props, double statevarval, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE,int calcTransport, int calcTwoPhaseNumericalDerivatives, int calcTwoPhasePsuedoAnalyticalDerivatives); //declaration; + EXPCONV double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *satprops, double statevarval, double Tsurft, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE,int calcTransport); //declaration; #if defined(__cplusplus) } #endif // __cplusplus From 88def9b74482c5234e3cc0e0259316bfc84db3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 14 Jan 2014 15:36:43 +0100 Subject: [PATCH 49/57] I will put this work on the self now. There are four ways with respect to computing partial derivatives, determined by "partialDersInputChoice": 1: none 2: partial derivatives of d wrt p,h,X In two-phase region: numerical differentiation for all derivatives In single phase region: dddX is numerical and others are analytical 3: partial derivatives of d wrt p,h,X In two-phase region: pseudo analytical (similar procedure as pure fluid - they give almost same result but with less CPU effort) In single phase region: dddX is numerical and others are analytical 4: partial derivatives of d and h wrt p,T,X In two-phase region: numerical differentiation for all derivatives In single phase region: dddX is numerical and others are analytical The fourth method is the only one that compares exactly with stepping forward in u,d,X (the baseline with most CPU effort) It is quicker in two-phase region compared to method 2, because T and P are equilibrium quantities.. Note that the dddX derivative is the difference in dddX1|X2=const-dddX2|X1=const --- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 150 +- Media/MethaneEthane.mo | 6 + Media/NH3_Water.mo | 5 +- Media/package.order | 2 + Testers/NH3_Water_setSatModel.mo | 4 +- Testers/NH3_Water_setStateModel.mo | 2 +- ...Water_setStateModel_test_partial_inputs.mo | 32 + Testers/package.order | 3 + _wrapper/cpptest/cpp_wrapped.cpp | 13 +- _wrapper/cpptest/cpp_wrapped2.cpp | 517 +++++-- _wrapper/cpptest/cpp_wrapped2.h | 81 ++ _wrapper/cpptest/refpropwrappertest_new.cpp | 55 +- _wrapper/src/BuildLIB-VS2010.bat | 5 +- _wrapper/src/refprop_library.h | 39 +- _wrapper/src/refprop_wrapper.cpp | 1236 +++++++++-------- _wrapper/src/refprop_wrapper.h | 2 +- 16 files changed, 1404 insertions(+), 748 deletions(-) create mode 100644 Media/MethaneEthane.mo create mode 100644 Testers/NH3_Water_setStateModel_test_partial_inputs.mo create mode 100644 _wrapper/cpptest/cpp_wrapped2.h diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 6f89dca..0b53709 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -16,9 +16,17 @@ partial package REFPROPMixtureTwoPhaseMedium "Merge all substance names to one string for refprop library"; constant Boolean debugmode=false "print messages in functions and wrapper library if run from command line"; - constant Boolean calcTransport=false; - constant Boolean calcTwoPhaseNumericalDerivatives=false; - constant Boolean calcTwoPhasePsuedoAnalyticalDerivatives=false; + + type PartialDersInputChoice = enumeration( + none "no partial derivatives is computed", + phX_numeric + "Numerical derivatives of density wrt. pressure, enthalpy and mass fraction is computed", + + phX_pseudoanalytic + "Pseudo analytical derivatives of density wrt. pressure, enthalpy and mass fraction is computed (not exact, but faster)", + + pTX_numeric + "Numerical derivatives of density and enthalpy wrt. pressure, temperature and mass fraction is computed"); constant FluidConstants[nS] rpConstants( each chemicalFormula="REFPROP Medium", @@ -39,23 +47,18 @@ partial package REFPROPMixtureTwoPhaseMedium //import REFPROP2Modelica.Interfaces.MixtureInputChoice; //constant MixtureInputChoice explicitVars = InputChoice.phX // "set of variables the model is explicit for, may be set to all combinations of p,h,T,d,s,d, REFPROP works internally with dT"; - // inputChoice = explicitVars, //"mediumName is being checked for consistency at flowports" + partial function partialREFPROP "Declaration of array props" //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() extends Modelica.Icons.Function; protected - Real[16 + 2*nX] props; - Real[6] ders; + Real[18 + 2*nX] props; + Real[12] ders; Real[3] trns; String errormsg=StrJoin(fill("xxxx", 64), "") "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; - // initial algorithm - // props :=fill(1, (16 + 2*nX)); - // ders :=fill(1, 19); - // trns :=fill(1, 3); - end partialREFPROP; function getProp_REFPROP @@ -70,6 +73,8 @@ partial package REFPROPMixtureTwoPhaseMedium input Real statevar2; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; input String errormsg; // input Integer debug=1; output Real val; @@ -88,8 +93,7 @@ partial package REFPROPMixtureTwoPhaseMedium errormsg, debugmode, calcTransport, - calcTwoPhaseNumericalDerivatives, - calcTwoPhasePsuedoAnalyticalDerivatives); + partialDersInputChoice); annotation (Include="#include ", Library="refprop_wrapper"); end getProp_REFPROP; @@ -149,6 +153,7 @@ partial package REFPROPMixtureTwoPhaseMedium input Real statevarval; input Real Tsurft=0 "additional temperature for surface tension function, in case of setSat_pX"; + input Boolean calcTransport=false; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; input String errormsg; output Real val; @@ -206,16 +211,15 @@ end SaturationProperties; redeclare record extends ThermodynamicState "Adapt this record to the returned values from one REFPROP call." -// Density d_l "density of liquid phase"; -// Density d_g "density of gaseous phase"; + Density d_l "density of liquid phase"; + Density d_g "density of gaseous phase"; // MassFraction x "void fraction"; // SpecificInternalEnergy u "Specific energy"; // MolarMass MM_l "Molar Mass of liquid phase"; // MolarMass MM_g "Molar Mass of gas phase"; -// MassFraction X_l[nX] -// "Composition of liquid phase (Mass fractions in kg/kg)"; -// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; + MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; + MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; // DerDensityByEnthalpy ddhp // "derivative of density wrt enthalpy at constant pressure"; // DerDensityByPressure ddph @@ -242,34 +246,21 @@ redeclare record extends ThermodynamicState // DerEnthalpyByPressure dhdp_T "dH/dP at constant temperature"; // DerEnthalpyByPressure dhdp_rho "dH/dP at constant density"; - DerDensityByEnthalpy drhodX_ph "drho/dh at constant pressure"; - DerDensityByEnthalpy drhodh_p "drho/dh at constant pressure"; - DerDensityByPressure drhodp_h "drho/dp at constant enthalpy"; + Real dddX_ph; + DerDensityByEnthalpy dddh_pX "drho/dh at constant pressure"; + DerDensityByPressure dddp_hX "drho/dp at constant enthalpy"; DynamicViscosity eta "dynamic viscosity"; ThermalConductivity lambda "thermal conductivity"; -end ThermodynamicState; + DerDensityByTemperature dddT_pX; + DerDensityByPressure dddp_TX; + DerEnthalpyByPressure dhdp_TX; + DerEnthalpyByTemperature dhdT_pX; + Real dddX_pT; + Real dhdX_pT; -// redeclare record extends ThermodynamicState -// "a selection of variables that uniquely defines the thermodynamic state" -// /* AbsolutePressure p "Absolute pressure of medium"; -// Temperature T "Temperature of medium"; -// MassFraction X[nX] "Composition (Mass fractions in kg/kg)";*/ -// MolarMass MM "Molar Mass of the whole mixture"; -// Density d(start=300) "density"; -// SpecificEnergy u "Specific energy"; -// SpecificEnthalpy h "Specific enthalpy"; -// SpecificEntropy s "Specific entropy"; -// Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp; -// Modelica.SIunits.SpecificHeatCapacityAtConstantVolume cv; -// VelocityOfSound c; -// MolarMass MM_l "Molar Mass of liquid phase"; -// MolarMass MM_g "Molar Mass of gas phase"; -// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; -// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; -// // Real GVF "Gas Void Fraction"; -// end ThermodynamicState; +end ThermodynamicState; // redeclare model extends BaseProperties "Base properties of medium" // equation @@ -374,13 +365,9 @@ end ThermodynamicState; input Real statevar2; input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; input FixedPhase phase "2 for two-phase, 1 for one-phase, 0 if not known"; - // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; output ThermodynamicState state "thermodynamic state record"; - // Real[:] props=getProps_REFPROP_check(statevars, fluidnames,statevar1, statevar2, X, phase); - /*protected - Real[16+2*nX] props; - String errormsg=StrJoin(fill("xxxx",64),"") - "Allocating memory, string will be written by C function";*/ algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); getProp_REFPROP( @@ -394,6 +381,8 @@ end ThermodynamicState; statevar2, X, phase, + partialDersInputChoice, + calcTransport, errormsg); assert(props[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); /* If q = 990 Then Modelica.Utilities.Streams.print(msg+String(z)) end if; @@ -407,6 +396,8 @@ end ThermodynamicState; X=X, molarMass=props[4], d=props[5], + d_l=props[6], + d_g=props[7], h=props[10], s=props[11], cv=props[12], @@ -416,11 +407,19 @@ end ThermodynamicState; q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], kappa=ders[2], beta=ders[3], - drhodX_ph=ders[4], - drhodh_p=ders[5], - drhodp_h=ders[6], + dddX_ph=ders[4], + dddh_pX=ders[5], + dddp_hX=ders[6], + dddp_TX=ders[7], + dddT_pX=ders[8], + dddX_pT=ders[9], + dhdp_TX=ders[10], + dhdT_pX=ders[11], + dhdX_pT=ders[12], eta=trns[2], - lambda=trns[3]); + lambda=trns[3], + X_l={props[16+i] for i in 1:nX}, + X_g={props[16+nX+i] for i in 1:nX}); if debugmode then Modelica.Utilities.Streams.print("Running state set to p,T,d,h,s (" @@ -531,6 +530,9 @@ end ThermodynamicState; redeclare replaceable function extends setState_phX "Calculates medium properties from p,h,X" // input String fluidnames; + + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; algorithm if debugmode then Modelica.Utilities.Streams.print("Running setState_phX(" + String(p) + "," @@ -541,7 +543,9 @@ end ThermodynamicState; p, h, X, - phase) ",fluidnames)"; + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; end setState_phX; redeclare function extends setBubbleState @@ -634,6 +638,9 @@ end ThermodynamicState; end setState_psX; redeclare replaceable partial function extends setState_pTX + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + algorithm if debugmode then Modelica.Utilities.Streams.print("Running setState_pTX(" + String(p) + "," @@ -644,7 +651,9 @@ end ThermodynamicState; p, T, X, - phase) ",fluidnames)"; + phase, + partialDersInputChoice, + calcTransport); //",fluidnames)"; end setState_pTX; function setState_ThX "Calculates medium properties from T,h,X" @@ -696,6 +705,7 @@ end ThermodynamicState; input Modelica.SIunits.MassFraction X[:] "Mass fractions"; input Real Tsurft=0 "additional temperature for surface tension function, in case of setSat_pX"; + input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm assert(size(X, 1) > 0, "The mass fraction vector must have at least 1 element."); @@ -706,6 +716,7 @@ end ThermodynamicState; satprops, statevarval, Tsurft, + calcTransport, X, errormsg); assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); @@ -732,13 +743,15 @@ end ThermodynamicState; input MassFraction X[nX] "Mass fractions"; input Real Tsurft=0 "additional temperature for surface tension function, in case of setSat_pX"; + input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm sat := setSat( "p", p, X, - Tsurft); + Tsurft, + calcTransport); end setSat_pX; redeclare replaceable function setSat_TX @@ -746,12 +759,14 @@ end ThermodynamicState; extends Modelica.Icons.Function; input Temperature T "temperature"; input MassFraction X[nX] "Mass fractions"; + input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm sat := setSat( "t", T, - X); + X, + calcTransport=calcTransport); end setSat_TX; redeclare function extends saturationPressure @@ -1040,7 +1055,7 @@ end ThermodynamicState; input ThermodynamicState state "thermodynamic state record"; output DerDensityByPressure ddph "Density derivative w.r.t. pressure"; algorithm - ddph := state.drhodp_h; + ddph := state.dddp_hX; end density_derp_h; redeclare function density_derh_p @@ -1050,7 +1065,7 @@ end ThermodynamicState; output DerDensityByEnthalpy ddhp "Density derivative w.r.t. specific enthalpy"; algorithm - ddhp := state.drhodh_p; + ddhp := state.dddh_pX; end density_derh_p; redeclare function density_derp_T @@ -1059,7 +1074,7 @@ end ThermodynamicState; input ThermodynamicState state "thermodynamic state record"; output DerDensityByPressure ddpT "Density derivative w.r.t. pressure"; algorithm - ddpT := state.drhodp_T; + ddpT := state.dddp_TX; end density_derp_T; redeclare function density_derT_p @@ -1068,17 +1083,18 @@ end ThermodynamicState; input ThermodynamicState state "thermodynamic state record"; output DerDensityByTemperature ddTp "Density derivative w.r.t. temperature"; algorithm - ddTp := state.drhodT_p; + ddTp := state.dddT_pX; end density_derT_p; -// redeclare function density_derX -// "Return density derivative w.r.t. mass fraction" -// extends Modelica.Icons.Function; -// input ThermodynamicState state "thermodynamic state record"; -// output Density[nX] dddX "Derivative of density w.r.t. mass fraction"; -// algorithm -// dddX := -// end density_derX; + redeclare function density_derX + "Return density derivative w.r.t. mass fraction" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output Density[nX] dddX "Derivative of density w.r.t. mass fraction"; + algorithm + dddX[1] := state.dddX_ph; + dddX[2:nX] := fill(0,nX-1); + end density_derX; function pressure_dsX "calls REFPROP-Wrapper, returns pressure" extends Modelica.Icons.Function; diff --git a/Media/MethaneEthane.mo b/Media/MethaneEthane.mo new file mode 100644 index 0000000..ddf76cd --- /dev/null +++ b/Media/MethaneEthane.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Media; +package MethaneEthane "MethaneEthane mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( + final substanceNames={"methane","ethane"}, + final debugmode=false); +end MethaneEthane; diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo index 913b096..7d4a04f 100644 --- a/Media/NH3_Water.mo +++ b/Media/NH3_Water.mo @@ -2,8 +2,5 @@ within REFPROP2Modelica.Media; package NH3_Water "Ammonia and water mixture by REFPROP library" extends Interfaces.REFPROPMixtureTwoPhaseMedium( final substanceNames={"ammoniaL","water"}, - final debugmode=false, - final calcTransport=true, - final calcTwoPhaseNumericalDerivatives=false, - final calcTwoPhasePsuedoAnalyticalDerivatives=true); + final debugmode=false); end NH3_Water; diff --git a/Media/package.order b/Media/package.order index 5841ec9..1cee419 100644 --- a/Media/package.order +++ b/Media/package.order @@ -2,3 +2,5 @@ Pentane R410mix Water NH3_Water +R410 +MethaneEthane diff --git a/Testers/NH3_Water_setSatModel.mo b/Testers/NH3_Water_setSatModel.mo index 6365c82..85f590f 100644 --- a/Testers/NH3_Water_setSatModel.mo +++ b/Testers/NH3_Water_setSatModel.mo @@ -16,8 +16,8 @@ equation p=50e5; X={0.5,0.5}; - sat = Medium.setSat_pX(p,X,450); - sat2 = Medium.setSat_TX(450,X); + sat = Medium.setSat_pX(p,X,450,calcTransport=true); + sat2 = Medium.setSat_TX(450,X,calcTransport=true); dewstate = Medium.setDewState(sat); bubstate = Medium.setBubbleState(sat); diff --git a/Testers/NH3_Water_setStateModel.mo b/Testers/NH3_Water_setStateModel.mo index abfde2f..a94e25d 100644 --- a/Testers/NH3_Water_setStateModel.mo +++ b/Testers/NH3_Water_setStateModel.mo @@ -27,7 +27,7 @@ equation h=3e5 + time*25e5; X={0.5,0.5}; - state = Medium.setState_phX(p,h,X); + state = Medium.setState_phX(p,h,X,calcTransport=true,partialDersInputChoice=3); q = Medium.vapourQuality(state); d = Medium.density(state); diff --git a/Testers/NH3_Water_setStateModel_test_partial_inputs.mo b/Testers/NH3_Water_setStateModel_test_partial_inputs.mo new file mode 100644 index 0000000..6ef00f1 --- /dev/null +++ b/Testers/NH3_Water_setStateModel_test_partial_inputs.mo @@ -0,0 +1,32 @@ +within REFPROP2Modelica.Testers; +model NH3_Water_setStateModel_test_partial_inputs + +package Medium = REFPROP2Modelica.Media.NH3_Water; +//package Medium2 = REFPROP2Modelica.Media.NH3_Water; + +// Medium.PartialDersInputChoice partialDersInputChoice = Medium.PartialDersInputChoice.none; +// Medium2.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.pTX_numeric; + + Medium.ThermodynamicState state; + Medium.ThermodynamicState state2; + +// input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + + parameter Medium.PartialDersInputChoice partialDersInputChoice0 = Medium.PartialDersInputChoice.none; + parameter Medium.PartialDersInputChoice partialDersInputChoice1 = Medium.PartialDersInputChoice.phX_numeric; + parameter Medium.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.phX_pseudoanalytic; + parameter Medium.PartialDersInputChoice partialDersInputChoice3 = Medium.PartialDersInputChoice.pTX_numeric; + +equation + p=50e5; + h=3e5+time*100e3; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X); + state2 = Medium.setState_phX(p,h,X,partialDersInputChoice=3); + +end NH3_Water_setStateModel_test_partial_inputs; diff --git a/Testers/package.order b/Testers/package.order index cbda809..4b136de 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -5,3 +5,6 @@ PropsPureSubstance R410mixTester Water_MixtureTwoPhase_pT PropsMixtureNH3H2O +NH3_Water_setSatModel +NH3_Water_setStateModel +numerical_jacobian_test_setState_ph diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index da7baf8..dd12e54 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -15,10 +15,9 @@ int main(int argc, char* argv[]){ double *props; double *ders; double *trns; - int DEBUG = 0; + int DEBUG = 1; int transport = 0; - int twophaseNumerical = 0; - int twophaseAnalytical = 1; + int partialDersInputChoice= 3; double *satprops; @@ -36,8 +35,8 @@ int main(int argc, char* argv[]){ // Allocate space for objects x = (double*) calloc(nX,sizeof(double)); - props = (double*) calloc(16+2*nX,sizeof(double)); - ders = (double*) calloc(9,sizeof(double)); + props = (double*) calloc(18+2*nX,sizeof(double)); + ders = (double*) calloc(12,sizeof(double)); trns = (double*) calloc(3,sizeof(double)); satprops = (double*) calloc(12+nX,sizeof(double)); @@ -48,7 +47,7 @@ int main(int argc, char* argv[]){ double p = 50.e5; double h = 3.0e5; - double dh = 0;//2.5e6; + double dh = 1500e3;//2.5e6; int N = 2; // steps in enthalpy int M = 1; // repetitions @@ -70,7 +69,7 @@ int main(int argc, char* argv[]){ for (int count = 0; count < N; count++) { h_in = h + dh * count / (N - 1); - res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG, transport, twophaseNumerical, twophaseAnalytical); + res = props_REFPROP((char*)"u", (char*)"ph", fluidname, ders, trns, props, p, h_in, x, 0, thepathChar, errormsg, DEBUG, transport, partialDersInputChoice); if (N*M #include #include -#include "cpp_wrapped.h" +#include "cpp_wrapped2.h" //#include "../src/refprop_library.h" #include @@ -16,31 +16,53 @@ int main(int argc, char* argv[]){ int nX=2; // Number of components double* x; x = (double*) calloc(nX,sizeof(double)); + x[0] = 0.25; + x[1] = 1.0 - x[0]; + + double href[ncmax]; + href[0] = 8295.6883966232; + href[1] = 14873.1879732343; + char thepathChar[255] = "c:\\Program Files (x86)\\Refprop"; char theSepChar[2] = "\\"; - x[0] = 0.5; - x[1] = 1.0 - x[0]; - double p = 50.e5; - double h = 3.0e5; - char hf[refpropcharlength*ncmax], hrf[lengthofreference+1], herr[errormessagelength+1],hfmix[refpropcharlength+1]; - double xmol[ncmax],xliq[ncmax],xvap[ncmax]; - double wm; long i=0, ierr=0; - double q,e,s,cv,cp,w,tt,dd,dl,dv; + HINSTANCE RefpropdllInstance; + RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\REFPROP.dll"); + + TDFLSHdll = (TDFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); + PHFLSHdll = (PHFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); + SETUPdll = (SETUPdll_POINTER) GetProcAddress(RefpropdllInstance,"SETUPdll"); + WMOLdll = (WMOLdll_POINTER) GetProcAddress(RefpropdllInstance,"WMOLdll"); + XMOLEdll = (XMOLEdll_POINTER) GetProcAddress(RefpropdllInstance,"XMOLEdll"); + + RMIX2dll = (RMIX2dll_POINTER) GetProcAddress(RefpropdllInstance,"RMIX2dll"); + RDXHMXdll = (RDXHMXdll_POINTER) GetProcAddress(RefpropdllInstance,"RDXHMXdll"); + PHIXdll = (PHIXdll_POINTER) GetProcAddress(RefpropdllInstance,"PHIXdll"); + PHI0dll = (PHI0dll_POINTER) GetProcAddress(RefpropdllInstance,"PHI0dll"); + + + PRESSdll = (PRESSdll_POINTER) GetProcAddress(RefpropdllInstance,"PRESSdll"); + ENTHALdll = (ENTHALdll_POINTER) GetProcAddress(RefpropdllInstance,"ENTHALdll"); + CRITPdll = (CRITPdll_POINTER) GetProcAddress(RefpropdllInstance,"CRITPdll"); + XMASSdll = (XMASSdll_POINTER) GetProcAddress(RefpropdllInstance,"XMASSdll"); + + + + // new fluid strcpy(hf,thepathChar); strcat(hf,theSepChar); strcat(hf,"fluids"); strcat(hf,theSepChar); - strcat(hf,"ammoniaL.fld|"); + strcat(hf,"methane.fld|"); strcat(hf,thepathChar); strcat(hf,theSepChar); strcat(hf,"fluids"); strcat(hf,theSepChar); - strcat(hf,"water.fld"); + strcat(hf,"ethane.fld"); strcpy(hfmix,thepathChar); strcat(hfmix,theSepChar); @@ -53,111 +75,420 @@ int main(int argc, char* argv[]){ i = nX; - HINSTANCE RefpropdllInstance; - RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\refprop.dll"); + //...Call SETUP to initialize the program + SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); + printf("ierr = %ld\n",ierr); - TDFLSHdll = (TDFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"TDFLSHdll"); - PHFLSHdll = (PHFLSHdll_POINTER) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - SETUPdll = (SETUPdll_POINTER) GetProcAddress(RefpropdllInstance,"SETUPdll"); - WMOLdll = (WMOLdll_POINTER) GetProcAddress(RefpropdllInstance,"WMOLdll"); - XMOLEdll = (XMOLEdll_POINTER) GetProcAddress(RefpropdllInstance,"XMOLEdll"); + double wm,xkg[ncmax]; +// WMOLdll(x,wm); + XMASSdll(x,xkg,wm); + printf("mass fraction [0] = %2.10f\n",xkg[0]); + printf("mass fraction [1] = %2.10f\n",xkg[1]); + printf("molecular weight = %2.10f\n\n",wm); +// here derivatives start + + int n = 2; // derivative wrt component n + double xn[ncmax],xp[ncmax]; + double delx = 0.00001; + double delx2 = 2 * delx; + + for (i = 0; i < nX; i++) { + xn[i] = x[i]; + xp[i] = x[i]; + } + xn[n-1] = xn[n-1] - delx; + xp[n-1] = xp[n-1] + delx; + double t = 250; + double d = 15; + + long im1=-1; + long i0=0; + long ip1=1; + double R, t0, d0, phi01, phi10, phig10, tau, delta; + double pn,pp,dpdxi1,hn,hp,dhdxi1,hrn,hrp,dhrdxi1; + double dpdxi2; + double dhdxi2; + + double hrefdiff; + + // test pressure equation.. + PRESSdll(t,d,x,pn); + printf("PRESSdll, p = %f\n",pn); + + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + pn = d * R * t * (1 + phi01); + printf("Definition, p = %f\n",pn); + + // test enthalpy equation.. + ENTHALdll(t,d,x,hn); + printf("ENTHALdll, h = %f\n",hn); + + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + PHIXdll(&ip1,&i0, tau, delta, x,phi10); + PHI0dll(&ip1, &i0, t, d, x, phig10); + hrefdiff = hn; + hn = R * t * (1 + phig10 + phi10 + phi01); + hrefdiff = hrefdiff - hn; + printf("Definition, h = %f\n",hn); + printf("hrefdiff = %5.10f\n",hrefdiff); + + // new test with new computed enthalpy reference from above at another temperature.. + t=t+50; + ENTHALdll(t,d,x,hn); + printf("ENTHALdll, h = %f\n",hn); + RMIX2dll(x, R); + RDXHMXdll(&im1,&i0,&i0,x,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, x,phi01); + PHIXdll(&ip1,&i0, tau, delta, x,phi10); + PHI0dll(&ip1, &i0, t, d, x, phig10); + hn = R * t * (1 + phig10 + phi10 + phi01) + x[0]*href[0] + x[1]*href[1]; + printf("Definition, h = %f\n",hn); + + t=250; // set back tempereture + d=15; + + + + printf("\n definitions work, proceed with numerical derivatives\n\n"); + +// PERFORM DERIVATIVES... + + + // negative increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xn, phi01); + PHIXdll(&ip1,&i0, tau, delta, xn, phi10); + PHI0dll(&ip1, &i0, t, d, xn, phig10); + pn = d * R * t * (1 + phi01); + hrn = R * t * (1 + phi10 + phi01); + hn = R * t * (1 + phig10 + phi10 + phi01) + xn[0]*href[0] + xn[1]*href[1]; + + // positive increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + PHIXdll(&ip1,&i0, tau, delta, xp, phi10); + PHI0dll(&ip1, &i0, t, d, xp, phig10); + pp = d * R * t * (1 + phi01); + hrp = R * t * (1 + phi10 + phi01); + hp = R * t * (1 + phig10 + phi10 + phi01) + xp[0]*href[0] + xp[1]*href[1]; + + // derivatives.. + dpdxi2 = (pp - pn) / delx2; +// dhrdxi2 = (hrp - hrn) / delx2; + dhdxi2 = (hp - hn) / delx2; + printf("dpdx2 = %f\n",dpdxi2); +// printf("dhrdxi = %f\n",dhrdxi2); + printf("dhdx2 = %f\n",dhdxi2); + + + + n = 1; // derivative wrt component n + for (i = 0; i < nX; i++) { + xn[i] = x[i]; + xp[i] = x[i]; + } + xn[n-1] = xn[n-1] - delx; + xp[n-1] = xp[n-1] + delx; + + // negative increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xn, phi01); + PHIXdll(&ip1,&i0, tau, delta, xn, phi10); + PHI0dll(&ip1, &i0, t, d, xn, phig10); + pn = d * R * t * (1 + phi01); + hrn = R * t * (1 + phi10 + phi01); + hn = R * t * (1 + phig10 + phi10 + phi01) + xn[0]*href[0] + xn[1]*href[1];; + + // positive increment + RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =d / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + PHIXdll(&ip1,&i0, tau, delta, xp, phi10); + PHI0dll(&ip1, &i0, t, d, xp, phig10); + pp = d * R * t * (1 + phi01); + hrp = R * t * (1 + phi10 + phi01); + hp = R * t * (1 + phig10 + phi10 + phi01) + xp[0]*href[0] + xp[1]*href[1];; + + // derivatives.. + dpdxi1 = (pp - pn) / delx2; +// dhrdxi1 = (hrp - hrn) / delx2; + dhdxi1= (hp - hn) / delx2; + printf("dpdx1 = %f\n",dpdxi1); + //printf("dhrdxi = %f\n",dhrdxi1); + printf("dhdx1 = %f\n",dhdxi1); + + printf("dpdx1-dpdx2 = %f\n",dpdxi1-dpdxi2); + printf("dhdx1-dhdx2 = %f\n",dhdxi1-dhdxi2); + + + // ' calculate d(p)/d(xi) and d(h)/d(xi) at constant T and V and + // ' The following do not work because R in d*R*T is changed as a function of x + double xnn[ncmax],xpp[ncmax]; + double dpdxi12,dhdxi12; + + xpp[0] = x[0]+delx; + xpp[1] = x[1]-delx; + xnn[0] = x[0]-delx; + xnn[1] = x[1]+delx; + + PRESSdll(t,d,xnn,pn); + PRESSdll(t,d,xpp,pp); + ENTHALdll(t,d,xnn,hn); + ENTHALdll(t,d,xpp,hp); + dpdxi12 = (pp - pn) / delx2; + printf("dpdx1-dpdx2 using PRESSdll = %f\n",dpdxi12); + dhdxi12 = (hp - hn) / delx2; + printf("dhdx1-dhdx2 using ENTHALdll = %f\n",dhdxi12); + + +// +// +// + + printf("\n"); + printf(" lets try mass basis, i.e. compute xmol from xkg +/- increments\n"); + printf(" NOTE that when we want to keep density on mass basis constant, then the molar density mol/L must be corrected when computing +/- increments\n"); + printf(" This is because when concentration (mass or mole) changes, so does molecular weight \n"); + printf(" (i.e. either moler density or mass density must change when keeping the other constant)\n"); + printf("\n"); + // ' calculate d(p)/d(xi) and d(h)/d(xi) at constant T and V and + // ' The following do not work because R in d*R*T is changed as a function of x + double xkgn[ncmax],xkgp[ncmax],wmn,wmp; + + XMASSdll(x,xkg,wm); + XMASSdll(x,xkgn,wm); + XMASSdll(x,xkgp,wm); + + xkgp[0] = xkg[0]+delx; + xkgp[1] = xkg[1]-delx; + xkgn[0] = xkg[0]-delx; + xkgn[1] = xkg[1]+delx; + XMOLEdll(xkgn,xnn,wmn); + XMOLEdll(xkgp,xpp,wmp); + + // diff dxdz numerically + double dxdz_num = (xkgp[0]-xkgn[0])/(xpp[0]-xnn[0]); + printf("dxdz_num = %f\n",dxdz_num); + + printf("dpdx_num = %f\n",(dpdxi1-dpdxi2)/dxdz_num); + + + + + +/* + printf("wmn = %f\n",wmn); + printf("wmp = %f\n",wmp); + + printf("xkgp[0] = %f\n",xkgp[0]); + printf("xkgp[1] = %f\n",xkgp[1]); + printf("xkgn[0] = %f\n",xkgn[0]); + printf("xkgn[1] = %f\n",xkgn[1]); + + printf("xpp[0] = %f\n",xpp[0]); + printf("xpp[1] = %f\n",xpp[1]); + printf("xnn[0] = %f\n",xnn[0]); + printf("xnn[1] = %f\n",xnn[1]); +*/ + + //double dpdxi12; + double dn=d*wm/wmn; // mass density should be kept constant even through we change concentration.. + PRESSdll(t,dn,xnn,pn); + double dp=d*wm/wmp; // mass density should be kept constant even through we change concentration.. + PRESSdll(t,dp,xpp,pp); + + dpdxi12 = (pp - pn) / (delx2); +// printf("pn = %f\n", pn); +// printf("pp = %f\n", pp); + printf("dpdx1 - dpdx2 using PRESSdll = %f\n",dpdxi12); + +// try do the conversion your self... + double wm1; + xkgp[0] = 1; + xkgp[1] = 0; + WMOLdll(xkgp,wm1); + printf("wm1 = %f\n",wm1); + double wm2; + xkgp[0] = 0; + xkgp[1] = 1; + WMOLdll(xkgp,wm2); + printf("wm2 = %f\n",wm2); + printf("wm = %f\n",wm); + +// printf("ratio %f\n",dpdxi12/(dpdxi1-dpdxi2)); + + /* + printf("x[0] = %f\n",x[0]); + printf("x[1] = %f\n",x[1]); + printf("xkg[0] = %f\n",xkg[0]); + printf("xkg[1] = %f\n",xkg[1]); + printf("dpdxi1 = %f\n",dpdxi1); + printf("dpdxi2 = %f\n",dpdxi2); + */ + double dxdz1,dxdz2,dzdx1,dzdx2; + dxdz1=wm1*x[1]*wm2/(wm*wm); // this one from maple + dzdx1=wm1*wm2*xkg[1]/((xkg[0]*wm2+xkg[1]*wm1)*(xkg[0]*wm2+xkg[1]*wm1)); + printf("dxdz1 = %f\n",dxdz1); + printf("1/dzdx1 = %f\n",1/dzdx1); + dxdz2=wm1*x[0]*wm2/(wm*wm); // this one from maple + dzdx2=wm1*wm2*xkg[0]/((xkg[0]*wm2+xkg[1]*wm1)*(xkg[0]*wm2+xkg[1]*wm1)); + printf("dxdz2 = %f\n",dxdz2); + printf("1/dzdx2 = %f\n",1/dzdx2); + printf("dpdx = %f\n",dpdxi1/dzdx1-dpdxi2/dzdx2); + printf("dpdx = %f\n",dpdxi1/dxdz1-dpdxi2/dxdz2); + printf("dpdxhmm = %f\n",(dpdxi1-dpdxi2)/(dxdz1-dxdz2)/2); - /* - //...Call SETUP to initialize the program - //long ,char*,char*,char*,long ,char*,long ,long ,long ,long - SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); + dxdz1 = wm1/wm - x[0]*wm1*(wm1-wm2)/(wm*wm); + dxdz2 = wm2/wm - x[1]*wm2*(wm2-wm1)/(wm*wm); + printf("dxdz1 = %f\n",dxdz1); + printf("dxdz2 = %f\n",dxdz2); - if (ierr != 0) printf("%s\n",herr); - //WMOLdll(x,wm); - XMOLEdll(x,xmol,wm); + printf("dpdx = %f\n",dpdxi1*dxdz1-dpdxi2*dxdz2); + printf("dpdx = %f\n",dpdxi1/dxdz1-dpdxi2/dxdz2); +// + printf("\n"); +// +// printf("dpdx = %f\n",dpdxi1*wm1/wm-dpdxi2*wm2/wm); +// printf("dpdx = %f\n",dpdxi1*wm/wm1-dpdxi2*wm/wm2); + + + + +// printf("\n"); +// printf(" I expect that dpdxi1 and dpdxi2 have some small error when transforming to mass basis, due to that molecular weight is changed when performing these numerical derivatives"); - double hmol = h*wm/1000.0; - double pkpa = p/1000.0; - PHFLSHdll(pkpa,hmol,xmol,tt,dd,dl,dv,xliq,xvap,q,e,s,cv,cp,w,ierr,herr,errormessagelength); + double p; + double h; + PRESSdll(t,d,x,p); + ENTHALdll(t,d,x,h); - printf("T = %f\n",tt); - printf("D = %f\n",dd); - printf("xmole = %f,%f\n",xmol[0],xmol[1]); - double pnew,hnew; - TDFLSHdll(tt,dd,xmol,pnew,dl,dv,xliq,xvap,q,e,hnew,s,cv,cp,w,ierr,herr,errormessagelength); -// ( t, D, z, p, Dl,Dv, x, y, q,e,h,s,cv,cp,w,ierr,herr) - printf("p = %f\n",pnew); - printf("h = %f\n",hnew/wm*1000); - */ - // new fluid - strcpy(hf,thepathChar); - strcat(hf,theSepChar); - strcat(hf,"fluids"); - strcat(hf,theSepChar); - strcat(hf,"methane.fld|"); - strcat(hf,thepathChar); - strcat(hf,theSepChar); - strcat(hf,"fluids"); - strcat(hf,theSepChar); - strcat(hf,"ethane.fld"); +///////////////////////////////////////////////////////// +/* + printf("\n try something else \n\n"); - //...Call SETUP to initialize the program - //long ,char*,char*,char*,long ,char*,long ,long ,long ,long - SETUPdll(i, hf, hfmix, hrf, ierr, herr,refpropcharlength*ncmax,refpropcharlength,lengthofreference,errormessagelength); - printf("ierr = %ld\n",ierr); + n=2; + for (i = 0; i < nX; i++) { + xkgn[i] = xkg[i]; + xkgp[i] = xkg[i]; + } + xkgn[n-1] = xkgn[n-1] - delx; + xkgp[n-1] = xkgp[n-1] + delx; - xmol[0]=0.5; - xmol[1]=0.5; - tt=250; - dd=15; //mol/dm^3 - double h1,h2,p1,p2,dpdx1_tv,dhdx1_tv; - double xmolnew[ncmax]; - double dx=1e-7; - xmolnew[0]=0.5+dx; - xmolnew[1]=0.5; + xnn[0] = xkgn[0] *wm/wm1; + xnn[1] = xkgn[1] *wm/wm2; + xpp[0] = xkgp[0] *wm/wm1; + xpp[1] = xkgp[1] *wm/wm2; - TDFLSHdll(tt,dd,xmol,p1,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); - printf("ierr = %ld\n",ierr); - printf("p1 = %f\n",p1); - printf("h1 = %f\n",h1); - printf("xmole1 = %1.10f,%1.10f\n",xmol[0],xmol[1]); - TDFLSHdll(tt,dd,xmolnew,p2,dl,dv,xliq,xvap,q,e,h2,s,cv,cp,w,ierr,herr,errormessagelength); - printf("ierr = %ld\n",ierr); - printf("p2 = %f\n",p2); - printf("h2 = %f\n",h2); - printf("xmole2 = %1.10f,%1.10f\n",xmolnew[0],xmolnew[1]); + printf("xkgp[0] = %f\n",xkgp[0]); + printf("xkgp[1] = %f\n",xkgp[1]); + printf("xkgn[0] = %f\n",xkgn[0]); + printf("xkgn[1] = %f\n",xkgn[1]); - dpdx1_tv = (p2-p1)/dx; - dhdx1_tv = (h2-h1)/dx; - printf("dpdx1_tv = %f\n",dpdx1_tv); - printf("dhdx1_tv = %f\n",dhdx1_tv); + printf("xpp[0] = %f\n",xpp[0]); + printf("xpp[1] = %f\n",xpp[1]); + printf("xnn[0] = %f\n",xnn[0]); + printf("xnn[1] = %f\n",xnn[1]); + + // XMOLEdll(xkgn,xnn,wmn); + // XMOLEdll(xkgp,xpp,wmp); + + RMIX2dll(x, R); + double Rkg=R/wm; + double dkg=d*wm; + + + RDXHMXdll(&im1,&i0,&i0,xnn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmn / d0; + PHIXdll(&i0,&ip1, tau, delta, xnn, phi01); + pn = dkg * Rkg * t * (1 + phi01); + + // positive increment + //RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xpp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmp / d0; + PHIXdll(&i0,&ip1, tau, delta, xpp, phi01); + pp = dkg * Rkg * t * (1 + phi01); + + // derivatives.. + dpdxi2 = (pp - pn) / delx2; + printf("dpdx2 = %f\n",dpdxi2); + + n=1; + for (i = 0; i < nX; i++) { + xkgn[i] = xkg[i]; + xkgp[i] = xkg[i]; + } + xkgn[n-1] = xkgn[n-1] - delx; + xkgp[n-1] = xkgp[n-1] + delx; + // double t = 250; + // XMOLEdll(xkgn,xnn,wmn); + // XMOLEdll(xkgp,xpp,wmp); + xnn[0] = xkgn[0] *wm/wm1; + xnn[1] = xkgn[1] *wm/wm2; + xpp[0] = xkgp[0] *wm/wm1; + xpp[1] = xkgp[1] *wm/wm2; + + // negative increment + //RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xnn,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta = dkg/wmn / d0; + PHIXdll(&i0,&ip1, tau, delta, xnn, phi01); + pn = dkg * Rkg * t * (1 + phi01); + + // positive increment + // RMIX2dll(x, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,xp,t0,d0,ierr,herr,errormessagelength); + tau = t0 / t; + delta =dkg/wmp / d0; + PHIXdll(&i0,&ip1, tau, delta, xp, phi01); + pp = dkg * Rkg * t * (1 + phi01); + + // derivatives.. + dpdxi1 = (pp - pn) / delx2; + + printf("dpdx1 = %f\n",dpdxi1); + + printf("dpdx1-dpdx2 = %f\n",dpdxi1-dpdxi2); + +*/ - double dpdx2_tv,dhdx2_tv; - xmolnew[0]=0.5; - xmolnew[1]=0.5+dx; - TDFLSHdll(tt,dd,xmol,p1,dl,dv,xliq,xvap,q,e,h1,s,cv,cp,w,ierr,herr,errormessagelength); - printf("ierr = %ld\n",ierr); - printf("p1 = %f\n",p1); - printf("h1 = %f\n",h1); - printf("xmole1 = %1.10f,%1.10f\n",xmol[0],xmol[1]); - TDFLSHdll(tt,dd,xmolnew,p2,dl,dv,xliq,xvap,q,e,h2,s,cv,cp,w,ierr,herr,errormessagelength); - printf("ierr = %ld\n",ierr); - printf("p2 = %f\n",p2); - printf("h2 = %f\n",h2); - printf("xmole2 = %1.10f,%1.10f\n",xmolnew[0],xmolnew[1]); - - dpdx2_tv = (p2-p1)/dx; - dhdx2_tv = (h2-h1)/dx; - printf("dpdx2_tv = %f\n",dpdx2_tv); - printf("dhdx2_tv = %f\n",dhdx2_tv); return 0; } diff --git a/_wrapper/cpptest/cpp_wrapped2.h b/_wrapper/cpptest/cpp_wrapped2.h new file mode 100644 index 0000000..84e0737 --- /dev/null +++ b/_wrapper/cpptest/cpp_wrapped2.h @@ -0,0 +1,81 @@ + +#ifndef CPP_WRAPPED_H +#define CPP_WRAPPED_H + +//#include "../src/refprop_library.h" + +// Some constants for REFPROP... defined by macros for ease of use +#define refpropcharlength 255 +#define refpropcharlong 10000 +#define filepathlength 255 +#define lengthofreference 3 +#define errormessagelength 255 +#define ncmax 20 // Note: ncmax is the max number of components +#define numparams 72 +#define maxcoefs 50 + +/* Define some new functions to access low-level refprop routines. + * + * The new functions should be used to compare the speed of the wrapper to the speed + * of the Fortran code and the Matlab implementation. + */ + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__) +# define __ISWINDOWS__ +# include +# define _CRT_SECURE_NO_WARNINGS +#elif __APPLE__ +# define __ISAPPLE__ +#elif __linux +# define __ISLINUX__ +#endif + +# define CALLCONV __stdcall +# define SETUPdll SETUPdll +# define WMOLdll WMOLdll +# define XMOLEdll XMOLEdll +# define PHFLSHdll PHFLSHdll +# define TDFLSHdll TDFLSHdll + +# define RMIX2dll RMIX2dll +# define RDXHMXdll RDXHMXdll +# define PHIXdll PHIXdll +# define PHI0dll PHI0dll +# define PRESSdll PRESSdll +# define ENTHALdll ENTHALdll +# define CRITPdll CRITPdll +# define MASSdll MASSdll + + +typedef void (CALLCONV *SETUPdll_POINTER)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); +typedef void (CALLCONV *WMOLdll_POINTER)(double *,double &); +typedef void (CALLCONV *XMOLEdll_POINTER)(double *,double *,double &); +typedef void (CALLCONV *PHFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,long &,char*,long ); +typedef void (CALLCONV *TDFLSHdll_POINTER)(double &,double &,double *,double &,double &,double &,double *,double *,double &,double &,double &,double &,double &,double &,double &,long &,char*,long ); + +typedef void (CALLCONV *RMIX2dll_POINTER)(double *,double &); +typedef void (CALLCONV *RDXHMXdll_POINTER)(long *,long *,long *,double *,double &,double &,long &,char*,long ); +typedef void (CALLCONV *PHIXdll_POINTER)(long *,long *,double &,double &,double *,double &); +typedef void (CALLCONV *PHI0dll_POINTER)(long *,long *,double &,double &,double *,double &); + +typedef void (CALLCONV *PRESSdll_POINTER)(double &,double &,double *,double &); +typedef void (CALLCONV *ENTHALdll_POINTER)(double &,double &,double *,double &); +typedef void (CALLCONV *CRITPdll_POINTER)(double *,double &,double &,double &,long &,char*,long ); +typedef void (CALLCONV *XMASSdll_POINTER)(double *,double *,double &); + +SETUPdll_POINTER SETUPdll; +WMOLdll_POINTER WMOLdll; +XMOLEdll_POINTER XMOLEdll; +PHFLSHdll_POINTER PHFLSHdll; +TDFLSHdll_POINTER TDFLSHdll; + +RMIX2dll_POINTER RMIX2dll; +RDXHMXdll_POINTER RDXHMXdll; +PHIXdll_POINTER PHIXdll; +PHI0dll_POINTER PHI0dll; +PRESSdll_POINTER PRESSdll; +ENTHALdll_POINTER ENTHALdll; +CRITPdll_POINTER CRITPdll; +XMASSdll_POINTER XMASSdll; + +#endif diff --git a/_wrapper/cpptest/refpropwrappertest_new.cpp b/_wrapper/cpptest/refpropwrappertest_new.cpp index f904c7b..13058c5 100644 --- a/_wrapper/cpptest/refpropwrappertest_new.cpp +++ b/_wrapper/cpptest/refpropwrappertest_new.cpp @@ -2,8 +2,8 @@ #include #include #include -#include "refprop_wrapper.h" -#include "refprop_library.h" +#include "../src/refprop_library.h" +#include "../src/refprop_wrapper.h" #include #include @@ -26,7 +26,8 @@ int main(int argc, char* argv[]){ int i; // int nX = argc-5; int DEBUG = 0; - + int transport = 0; + int partialDersInputChoice= 3; /* @@ -82,29 +83,42 @@ x[1] = 1.0-x[0]; */ // double p; - double h; - double dh; - int N=500; +// double h; +// double dh; +// int N=500; +// +// double* T_save; +// double* h_in; +// T_save = (double*) calloc(N,sizeof(double)); +// h_in = (double*) calloc(N,sizeof(double)); - double* T_save; - double* h_in; - T_save = (double*) calloc(N,sizeof(double)); - h_in = (double*) calloc(N,sizeof(double)); +//p=50e5; +//h=3e5; +//dh=25e5; -p=50e5; -h=3e5; -dh=25e5; -//std::string thepath = std::string("c:\\Program Files (x86)\\Refprop"); -std::string thepath = std::string("/opt/refprop"); +std::string thepath = std::string("c:\\Program Files (x86)\\Refprop\\"); +//std::string thepath = std::string("/opt/refprop"); char thepathChar[255]; - strcpy(thepathChar,thepath.c_str()); -props_REFPROP ("", "ph", "ammoniaL|water" , ders, trns, props, p, h, x, 0, thepathChar , errormsg, DEBUG); +//props_REFPROP ("", "ph", "ammoniaL|water" , ders, trns, props, p, h, x, 0, thepathChar , errormsg, DEBUG, transport, partialDersInputChoice); + +x[0] = 0.3479106451; //mass gives 0.5 mole +x[1] = 0.6520893549; //mass + +t = 250; +d = 15*23.0559200000; // mol/L * g/mol = kg/m3 + +props_REFPROP ("", "td", "methane|ethane" , ders, trns, props, t, d, x, 0, thepathChar , errormsg, DEBUG, transport, partialDersInputChoice); + +printf("q=%f [kg/kg]\n",props[7]); +printf("p=%f [Pa]\n",props[1]); - //printf("q=%f [kg/kg]\n",props[7]); + + +/* //Then at the beginning: time_t tstart, tend; @@ -114,7 +128,7 @@ props_REFPROP ("", "ph", "ammoniaL|water" , ders, trns, props, p, h, for (count = 0; count < N; count++) { h_in[count] = h+dh*count/(N-1); - props_REFPROP ("u", "ph", "ammoniaL|water" , ders, trns, props, p, h_in[count], x, 0, thepathChar , errormsg, DEBUG); + props_REFPROP ("u", "ph", "ammoniaL|water" , ders, trns, props, p, h_in[count], x, 0, thepathChar , errormsg, DEBUG, transport, partialDersInputChoice); T_save[count] = props[2]; //printf("T=%f [K]\n",props[2]); @@ -126,6 +140,7 @@ props_REFPROP ("", "ph", "ammoniaL|water" , ders, trns, props, p, h, myString1 << "It took "<< difftime(tend, tstart) <<" second(s)."<< std::endl; printf("%s",myString1.str().c_str()); + std::ostringstream s; for (count = 0; count < N; count++) { @@ -144,7 +159,7 @@ printf("%s",myString1.str().c_str()); //failed to create the file printf("failed to create the file"); } - +*/ //strcpy(fluidname,argv[1]);//water; /*p=atof(argv[2]);//2000; diff --git a/_wrapper/src/BuildLIB-VS2010.bat b/_wrapper/src/BuildLIB-VS2010.bat index b79d84b..490bc33 100644 --- a/_wrapper/src/BuildLIB-VS2010.bat +++ b/_wrapper/src/BuildLIB-VS2010.bat @@ -11,4 +11,7 @@ erase *.obj copy refprop_wrapper.lib "C:\Program Files (x86)\Dymola 2013\bin\lib\" copy refprop_wrapper.h "C:\Program Files (x86)\Dymola 2013\Source\" -copy refprop_library.h "C:\Program Files (x86)\Dymola 2013\Source\" \ No newline at end of file +copy refprop_library.h "C:\Program Files (x86)\Dymola 2013\Source\" +copy refprop_wrapper.lib "C:\Program Files (x86)\Dymola 2014\bin\lib\" +copy refprop_wrapper.h "C:\Program Files (x86)\Dymola 2014\Source\" +copy refprop_library.h "C:\Program Files (x86)\Dymola 2014\Source\" \ No newline at end of file diff --git a/_wrapper/src/refprop_library.h b/_wrapper/src/refprop_library.h index 77b1495..61cc828 100644 --- a/_wrapper/src/refprop_library.h +++ b/_wrapper/src/refprop_library.h @@ -131,7 +131,10 @@ # define XMASSdll XMASSdll # define XMOLEdll XMOLEdll - +# define RMIX2dll RMIX2dll +# define RDXHMXdll RDXHMXdll +# define PHIXdll PHIXdll +# define PHI0dll PHI0dll #elif defined(__ISLINUX__) // defined(__ISWINDOWS__) // Define compiler specific calling conventions @@ -247,6 +250,12 @@ # define WMOLdll wmoldll_ # define XMASSdll xmassdll_ # define XMOLEdll xmoledll_ + +# define RMIX2dll rmix2dll_ +# define RDXHMXdll rdxhmxdll_ +# define PHIXdll phixdll_ +# define PHI0dll phi0dll_ + #else // #elif defined(__ISLINUX__) // Set some dummy names for the compiler # define CALLCONV @@ -351,6 +360,12 @@ # define WMOLdll wmoldll # define XMASSdll xmassdll # define XMOLEdll xmoledll + +# define RMIX2dll rmix2dll +# define RDXHMXdll rdxhmxdll +# define PHIXdll phixdll +# define PHI0dll phi0dll + #endif // else branch // // @@ -467,6 +482,12 @@ #define WMOLdll_NAME FUNCTION_NAME(WMOLdll) #define XMASSdll_NAME FUNCTION_NAME(XMASSdll) #define XMOLEdll_NAME FUNCTION_NAME(XMOLEdll) + +#define RMIX2dll_NAME FUNCTION_NAME(RMIX2dll) +#define RDXHMXdll_NAME FUNCTION_NAME(RDXHMXdll) +#define PHIXdll_NAME FUNCTION_NAME(PHIXdll) +#define PHI0dll_NAME FUNCTION_NAME(PHI0dll) + // // I'll try to follow this example from: // http://www.gershnik.com/tips/cpp.asp @@ -578,7 +599,15 @@ extern "C" { typedef void (CALLCONV WMOLdll_TYPE)(double *,double &); typedef void (CALLCONV XMASSdll_TYPE)(double *,double *,double &); typedef void (CALLCONV XMOLEdll_TYPE)(double *,double *,double &); -// + + typedef void (CALLCONV RMIX2dll_TYPE)(double *,double &); + typedef void (CALLCONV RDXHMXdll_TYPE)(long *,long *,long *,double *,double &,double &,long &,char*,long ); + typedef void (CALLCONV PHIXdll_TYPE)(long *,long *,double &,double &,double *,double &); + typedef void (CALLCONV PHI0dll_TYPE)(long *,long *,double &,double &,double *,double &); + + + + // // Disabled because we prefer pointers here! // // Declare the functions for direct access, // RPVersion_TYPE RPVersion; @@ -785,6 +814,12 @@ extern "C" { typedef XMASSdll_TYPE * XMASSdll_POINTER; typedef XMOLEdll_TYPE * XMOLEdll_POINTER; + typedef RMIX2dll_TYPE * RMIX2dll_POINTER; + typedef RDXHMXdll_TYPE * RDXHMXdll_POINTER; + typedef PHIXdll_TYPE * PHIXdll_POINTER; + typedef PHI0dll_TYPE * PHI0dll_POINTER; + + #if defined(__cplusplus) } // extern "C" diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 1652c98..aff47f8 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -76,7 +76,7 @@ std::string loadedFluids; * properties using the molecular weight. It is stored in g/mol. */ long kq = 2; // all qualities are calculated on a mass basis -static const double noValue = -1e+10; +static const double noValue = 0; //static const std::string FLUIDS_PATH = "fluids"; //static const std::string LIN_LIBRARY = "librefprop.so"; @@ -95,57 +95,40 @@ static const double noValue = -1e+10; bool debug; // set the debug flag bool calcTrans; -bool calcTwoPhaseNumDers; -bool calcTwoPhasePsuedoAnalDers; +//bool calcTwoPhaseNumDers; +//bool calcTwoPhasePsuedoAnalDers; +//bool dynstatesTPX; +int PartialDersInputChoice; //long lerr; // Error return mechanism double dhelp = noValue; - -/* - * Properties for saturation states. "dew" refers to the dew point and - * "bub" describes the bubble point. - */ - -double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat,dxmollsat[ncmax],dxmolvsat[ncmax],dplsat,dhlsat,dslsat,dcvlsat,dcplsat,dwlsat,dpvsat,dhvsat,dsvsat,dcvvsat,dcpvsat,dwvsat,dtlsat,dtvsat; - -// TODO hmm it does not seem that these are ever used? -double dtdew, dpdew, ddldew, ddvdew, dtbub, dpbub, ddlbub, ddvbub; -int flushSaturation() { - dtdew=noValue; - dpdew=noValue; - ddldew=noValue; - ddvdew=noValue; - dtbub=noValue; - dpbub=noValue; - ddlbub=noValue; - ddvbub=noValue; - if (debug) printf ("Finished flushing saturation properties.\n"); - return 0; -} - +// Properties for setSat functions +double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat, + dxmollsat[ncmax],dxmolvsat[ncmax],dplsat,dhlsat,dslsat, + dcvlsat,dcplsat,dwlsat,dpvsat,dhvsat,dsvsat,dcvvsat,dcpvsat, + dwvsat,dtlsat,dtvsat; /* * Most of the fluid properties are stored here. There are arrays for * composition information as well as single values for the other * properties. * The flush function gets called when the state changes and the - * previously calculated are not valid anymore. A change of state also leads - * to changed saturation conditions. + * previously calculated are not valid anymore. */ double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta; -double deta, dtcx; - -//double ddpdd, dd2pdd2, ddpdt, ddddt, ddddp, dd2pdt2, dd2pdtd, ddhdt; +double *dxkg; -//double ddhdt_d, ddhdt_p, ddhdd_t, ddhdd_p, ddhdp_t, ddhdp_d; - -//double dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; +// viscosity and thermal conductivity +double deta, dtcx; -double ddddp_h, ddddh_p, ddddX_ph; +// partial derivatives +double ddddp_h, ddddh_p, ddddX_ph, + ddddp_T, ddddT_p, ddddX_pT, + ddhdp_T, ddhdT_p, ddhdX_pT; int flushProperties(){ dt=noValue; @@ -179,8 +162,15 @@ int flushProperties(){ ddddp_h=noValue; ddddh_p=noValue; + ddddp_T=noValue; + ddddT_p=noValue; + ddddX_pT=noValue; + ddhdp_T=noValue; + ddhdT_p=noValue; + ddhdX_pT=noValue; + if (debug) printf ("Finished flushing normal fluid properties.\n"); - return flushSaturation(); + return 0; } @@ -323,6 +313,11 @@ WMOLdll_POINTER WMOLdll; XMASSdll_POINTER XMASSdll; XMOLEdll_POINTER XMOLEdll; +RMIX2dll_POINTER RMIX2dll; +RDXHMXdll_POINTER RDXHMXdll; +PHIXdll_POINTER PHIXdll; +PHI0dll_POINTER PHI0dll; + /* * Helper function to split strings the @@ -783,6 +778,12 @@ double setFunctionPointers() { WMOLdll = (WMOLdll_POINTER) getFunctionPointer((char *) WMOLdll_NAME); XMASSdll = (XMASSdll_POINTER) getFunctionPointer((char *) XMASSdll_NAME); XMOLEdll = (XMOLEdll_POINTER) getFunctionPointer((char *) XMOLEdll_NAME); + + RMIX2dll = (RMIX2dll_POINTER) getFunctionPointer((char *) RMIX2dll_NAME); + RDXHMXdll = (RDXHMXdll_POINTER) getFunctionPointer((char *) RDXHMXdll_NAME); + PHIXdll = (PHIXdll_POINTER) getFunctionPointer((char *) PHIXdll_NAME); + PHI0dll = (PHI0dll_POINTER) getFunctionPointer((char *) PHI0dll_NAME); + if (debug) printf ("Function pointers set to macro values.\n"); return OK; } @@ -1122,8 +1123,11 @@ double get_dhdp_d_modelica() { //dH/dP at constant density [J/(mol-kPa)] // Derivatives // Derivative of density with respect to enthalpy at constant pressure double get_dddX_ph_modelica(){ - if (dwvap==noValue) WMOLdll(dxmolv,dwvap); - return ddddX_ph*dwm*dwm/dwvap; // [mol/l * mol/molvap] * g/mol * g/mol * molvap/gvap * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gvap +// double dxmoltmp[ncmax],dwm1; +// dxmoltmp[0]=1; +// dxmoltmp[1]=0; +// WMOLdll(dxmoltmp,dwm1); // TODO this must be molecular weight of species 1 instead of vap... Take a look at how ddddX_pt is computed!!! + return ddddX_ph;//*dwm*dwm/dwm1; // [mol/l * mol/mol1] * g/mol * g/mol * mol1/g1 * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gi } double get_dddh_p_modelica(){ return ddddh_p*dwm*dwm/1000.; // [mol/l * mol/J] * g/mol * g/mol * 1e-3kg/g * 1e-3kg/g / 1e-3 m3/L = kg/m3 * kg/J @@ -1186,142 +1190,6 @@ double getValue(std::string out) { return noValue; } -///* -// * Improvised derivative computing. These functions are called -// * after properties were calculated. Hence, we have density and -// * pressure available. REFPROP is formulated with explicit d and -// * T it should not take too much extra time. -// */ -//double spare3,spare4,spare5,spare6,spare7[ncmax],spare8[ncmax],spare9,spare10,spare11,spare12,spare13,spare14; -//double deltaH,hLow,hHigh,deltaP,pLow,pHigh,rhoLow,rhoHigh; -//int setExtra(bool debug, long lerr, char* errormsg){ -// double rho,T; -// rho = getValue("d"); -// T = getValue("T"); -// if ((rho!=noValue)&&(T!=noValue)) { // call explicit function -// // get derivative of density with respect to pressure from Refprop library -// if (debug) printf("Calling THERM2 with %f and %f.\n",dt,dd); -// THERM2dll (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); -//// deltaP = 1.; -//// pLow = dp - 0.5*deltaP; -//// pHigh = dp + 0.5*deltaP; -//// rhoLow = 0; -//// rhoHigh = 0; -//// //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pLow,dh); -//// PHFLSHdll(pLow,dh,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -//// if (debug) printf("Calling PHFLSH with %f and %f.\n",pHigh,dh); -//// PHFLSHdll(pHigh,dh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -//// if (debug) printf("Setting ddddp from %f and %f.\n",rhoHigh,rhoLow); -//// ddddp = (rhoHigh-rhoLow) / (pHigh-pLow); -// -// // get derivative of density with respect to enthalpy numerically -// deltaH = 20.; -// hLow = dh - 0.5*deltaH; -// hHigh = dh + 0.5*deltaH; -// rhoLow = 0; -// rhoHigh = 0; -// //PHFLSHdll(dp,hLow,dxmol,dt,dd,ddl,ddv,dxmoll,dxmolv,dqmol,de,ds,dCv,dCp,dw,lerr,errormsg,errormessagelength); -// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hLow); -// PHFLSHdll(dp,hLow,dxmol,spare3,rhoLow,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -// if (debug) printf("Calling PHFLSH with %f and %f.\n",dp,hHigh); -// PHFLSHdll(dp,hHigh,dxmol,spare3,rhoHigh,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12,spare13,spare14,lerr,errormsg,errormessagelength); -// if (debug) printf("Setting dddhp from %f and %f.\n",rhoHigh,rhoLow); -// ddddh = (rhoHigh-rhoLow) / (hHigh-hLow); -// } else { // We have a problem! -// printf("Derivative calculation called at the wrong time: rho=%f and T=%f\n",rho,T); -// } -// return 0; -//} - -//int updateExtra(double *der, long lerr){ -//// c inputs: -//// c t--temperature [K] -//// c rho--molar density [mol/L] -//// c x--composition [array of mol frac] -//// c outputs: -//// c p--pressure [kPa] -//// c e--internal energy [J/mol] -//// c h--enthalpy [J/mol] -//// c s--entropy [J/mol-K] -//// c Cv--isochoric heat capacity [J/mol-K] -//// c Cp--isobaric heat capacity [J/mol-K] -//// c w--speed of sound [m/s] -//// c Z -//// c hjt -//// c A -//// c G -//// c xkappa -//// c beta -//// c dPdrho -//// c d2PdD2 -//// c dPT -//// c drhodT -//// c drhodP -//// c d2PT2 -//// c d2PdTD -//// c sparei--2 space holders for possible future properties -// -// -//// subroutine DHD1(t,rho,x,dhdt_d,dhdt_p,dhdd_t,dhdd_p,dhdp_t,dhdp_d) -////c -////c compute partial derivatives of enthalpy w.r.t. t, p, or rho at constant -////c t, p, or rho as a function of temperature, density, and composition -////c -////c inputs: -////c t--temperature [K] -////c rho--molar density [mol/L] -////c x--composition [array of mol frac] -////c outputs: -////c get_dhdt_d_modelica(); --dH/dT at constant density [J/(mol-K)] -////c get_dhdt_p_modelica(); --dH/dT at constant pressure [J/(mol-K)] -////c get_dhdd_t_modelica(); --dH/drho at constant temperature [(J/mol)/(mol/L)] -////c get_dhdd_p_modelica(); --dH/drho at constant pressure [(J/mol)/(mol/L)] -////c get_dhdp_t_modelica(); --dH/dP at constant temperature [J/(mol-kPa)] -////c get_dhdp_d_modelica(); --dH/dP at constant density [J/(mol-kPa)] -// -//// double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, -//// ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, -//// - - -// -// -// -// -// getDDDH -// -// -// -// -//// THERM2dll (dt,dd,dxmol,spare5,spare6,spare8,spare9,dCv,dCp,dw,dZ,dhjt,dA,dG,dxkappa,dbeta,ddpdd,dd2pdd2,ddpdt,ddddt,ddddp,dd2pdt2,dd2pdtd,spare3,spare4); -// -// //ASSIGN VALUES TO RETURN ARRAY -// der[0] = lerr;//error code -// der[1] = getP_modelica(); //pressure in Pa -// der[2] = getT_modelica(); //Temperature in K -// der[3] = getWM_modelica(); //molecular weight -// der[4] = getD_modelica(); //density -// der[5] = getDL_modelica(); //density of liquid phase -// der[6] = getDV_modelica(); //density of liquid phase -// der[7] = getQ_modelica(); //vapor quality on a mass basis [mass vapor/total mass] (q=0 indicates saturated liquid, q=1 indicates saturated vapor) -// der[8] = getE_modelica(); //internal energy -// der[9] = getH_modelica(); //specific enthalpy -// der[10] = getS_modelica(); //specific entropy -// der[11] = getCV_modelica(); // heat capacity -// der[12] = getCP_modelica(); // heat capacity -// der[13] = getW_modelica(); //speed of sound -// der[14] = getDDDH_modelica(); //ddhp -// der[15] = getDDDP_modelica(); //ddph -// der[16] = getWML_modelica(); -// der[17] = getWMV_modelica(); -// -// double dxlkg[ncmax], dxvkg[ncmax]; -// -// -// return 0; -//} - int updateDers(double *ders, long lerr){ @@ -1349,12 +1217,20 @@ int updateDers(double *ders, long lerr){ ders[20] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] */ // TODO - I have reduced the variables thrown back.. Why us jtc, a, g derivatives here? - ders[0] = lerr;//error code - ders[1] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] - ders[2] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] - ders[3] = get_dddX_ph_modelica(); // dH/dP at constant density [J/(kg-Pa)] + ders[0] = lerr;//error code + ders[1] = getXKAPPA_modelica(); // isothermal compressibility (= -1/V dV/dP = 1/rho dD/dP) [1/Pa] + ders[2] = getBETA_modelica(); // volume expansivity (= 1/V dV/dT = -1/rho dD/dT) [1/K] + ders[3] = get_dddX_ph_modelica(); // dD/dX at constant p,h ders[4] = get_dddh_p_modelica(); // dD/dh at constant pressure [kg/m3 * kg/J] ders[5] = get_dddp_h_modelica(); // dD/dp at constant enthalpy [kg/(m3.Pa)] + + ders[6] = ddddp_T*dwm/1000; // (mol/L * 1/kPa) * g/mol / 1000 g/kg * 1000L/m3 / 1000 Pa/kPa + ders[7] = ddddT_p*dwm; // (mol/L * 1/K) * g/mol / 1000 g/kg * 1000L/m3 + ders[8] = ddddX_pT;// Done in function *dwm*dwm/dw1; // [mol/l * mol/molvap] * g/mol * g/mol * moli/gi * 1e-3kg/g / 1e-3 m3/L = kg/m3 * g/gi + ders[9] = ddhdp_T/dwm; // (J/mol * 1/kPa) / g/mol * 1000 g/kg / 1000 Pa/kPa + ders[10] = ddhdT_p/dwm*1000; // (J/mol * 1/K) / g/mol * 1000 g/kg + ders[11] = ddhdX_pT;// Done in function /dwm*1000*dwm/dw1; // (J/mol * mol/molvap) / g/mol * 1000 g/kg * g/mol * molvap/gvap = J/kg * g/gvap + return 0; } @@ -1370,371 +1246,581 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ // THERM2dll(dt, dd, dxmol, spare5, spare6, spare9, spare10, dCv, dCp, dw,dZ, dhjt, dA, dG, dxkappa, dbeta, ddpdd, dd2pdd2, ddpdt, ddddt,ddddp, dd2pdt2, dd2pdtd, spare3, spare4); // we want to get props depending on quality below.. - if (dqmol < 0. || dqmol > 1.) { // single-phase region - if (debug) printf ("Using single-phase derivatives.\n"); + if (PartialDersInputChoice==4) { // use TPX numeric derivs - if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); - THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); - // analytical derivatives - ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; - ddddh_p = -dbeta*dd/dCp; - - // numerical derivative for ddddzi - double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz,dpdz_td,dhdz_td; - - dpdT_zv = dbeta/dxkappa; - dpdv_Tz= -dd/dxkappa; - dhdT_vz = dCv+dbeta/(dd*dxkappa); - dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); - -// printf("dxmol,%f,%f\n",dxmol[0],dxmol[1]); -// printf("dpdT_zv,%f\n",dpdT_zv); -// printf("dpdv_Tz,%f\n",dpdv_Tz); -// printf("dhdT_vz,%f\n",dhdT_vz); -// printf("dhdT_vz,%f\n",dhdv_Tz); - - double dxmolnew[ncmax]; - double pnew,hnew; - double dvdz_ph; - - dxmolnew[0]=dxmol[0]+0.001; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const - dxmolnew[1]=dxmol[1]-0.001; // TODO, check refprop if it recomputes concentration - PRESSdll (dt,dd,dxmolnew,pnew); // this function need not sum(z)=1, or? --- it does - ENTHALdll (dt,dd,dxmolnew,hnew); // this function need not sum(z)=1, or? --- it does - dpdz_td = (pnew-dp)/0.001; - dhdz_td = (hnew-dh)/0.001; - -// printf("xmol,%f,%f\n",dxmolnew[0],dxmolnew[1]); -// printf("d,%f\n",dd); -// printf("t,%f\n",dt); -// printf("p,%f\n",dp); -// printf("pnew,%f\n",pnew); -// printf("h,%f\n",dh); -// printf("hnew,%f\n",hnew); -// printf("dpdz_td,%f\n",dpdz_td); -// printf("dhdz_td,%f\n",dhdz_td); - - // expression from jacobian matrix transformation - dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); -// printf("dvdz_ph,%f\n",dvdz_ph); - ddddX_ph = -dd*dd*dvdz_ph; // this is still in refprop units, so X is molvap/mol.. -// printf("ddddX_ph ,%f\n",ddddX_ph); - - - } else { // two-phase region, get derivative of density - - // These are not computed in two-phase! - dxkappa=noValue; - dbeta=noValue; + // analytical derivatives of density: + ddddT_p = -dbeta*dd; + ddddp_T = dxkappa*dd; - if (calcTwoPhasePsuedoAnalDers) { - if (debug) printf ("Using Analytical twophase derivatives\n"); - -// // TODO the below analytical derivs are wrong since saturated liquid and vapor concentrations change along evaporation.. - - - /* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) - */ - - //compute saturated vapor state - long kph2 = 2; - double dt_v,ddv_v,dCv_v,dCp_v,dwm_v,dxkappa_v,dbeta_v,h_v,s_v; - SATPdll(dp,dxmol,kph2,dt_v,spare3,ddv_v,spare2,spare1,lerr,errormsg,errormessagelength); - THERM2dll(dt_v, ddv_v, dxmol, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); - - //compute saturated liquid state - long kph1 = 1; - double dt_l,ddl_l,dCv_l,dCp_l,dwm_l,dxkappa_l,dbeta_l,h_l,s_l; - SATPdll(dp,dxmol,kph1,dt_l,ddl_l,spare3,spare2,spare1,lerr,errormsg,errormessagelength); - THERM2dll(dt_l, ddl_l, dxmol, spare3, spare4, h_l, s_l, dCv_l, dCp_l, dwm_l,spare2, spare10, spare11, spare12, dxkappa_l, dbeta_l, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); - - // compute partials - double dvdh_p,dTdp_clasius, dhdpL,dhdpV,dvdpL,dvdpV,dxdp_h,dvdp_h; - // compute drhodh_p - dvdh_p = (1/ddv_v - 1/ddl_l)/(h_v-h_l); - ddddh_p = -dd*dd*dvdh_p; - // compute drhodp_h - dTdp_clasius = (1/ddv_v - 1/ddl_l)/(s_v-s_l); - dhdpL = 1/ddl_l*(1-dbeta_l*dt_l)+dCp_l*dTdp_clasius; - dhdpV = 1/ddv_v*(1-dbeta_v*dt_v)+dCp_v*dTdp_clasius; - dvdpL = dbeta_l*1/ddl_l*dTdp_clasius-dxkappa_l*1/ddl_l; - dvdpV = dbeta_v*1/ddv_v*dTdp_clasius-dxkappa_v*1/ddv_v; - dxdp_h = (dhdpL + dqmol * (dhdpV-dhdpL))/(h_l-h_v); - dvdp_h = dvdpL+dxdp_h*(1/ddv_v-1/ddl_l)+dqmol*(dvdpV-dvdpL); - ddddp_h = -dd*dd*dvdp_h; - - - - // numerical derivative for ddddzi, that ensures xmol is between 0 and 1 - double HA,HB,smooth,DX,dxmolnew[ncmax],dlow,dhigh; - HA = 0.925*(h_v-h_l)+h_l; - HB = 0.975*(h_v-h_l)+h_l; - - /* - // using PHFLSH to get numerical derivative ddddzi - DX=0.005; - if (dh < HA) { - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 - PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); - ddddX_ph = (dlow-dd)/DX; - } else if (dh > HB) { - DX=-DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 - PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); - ddddX_ph = (dhigh-dd)/DX; - } else { - smooth=(dh-HA)/(HB-HA); - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); - DX = -DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); - ddddX_ph = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); - } - */ - - // Using TPFLSH to get numerical derivative ddddzi - double dhdT_pX, dddT_pX,hlow,hhigh,dddX_pT,dhdX_pT; - - dhdT_pX = (h_v - h_l)/(dt_v-dt_l); - //dvdT_p = (1/ddv_v - 1/ddl_l)/(dt_v-dt_l); - dddT_pX = -dd*dd*(1/ddv_v - 1/ddl_l)/(dt_v-dt_l); - - DX=0.0025; - if (dh < HA) { - //DX = DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 - TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dlow-dd)/(DX); - dhdX_pT = (hlow-dh)/(DX); - } else if (dh > HB) { - DX = -DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dhigh-dd)/(DX); - dhdX_pT = (hhigh-dh)/(DX); - } else { // something smooth - smooth=(dh-HA)/(HB-HA); - //DX = DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - DX = -DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); - dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); - } - ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; - - - } else if (calcTwoPhaseNumDers) { - if (debug) printf ("Using Numerical two phase derivatives\n"); - - // in the following HA and HB are points in two-phase, where the numerical derivative changes "the sign of change", e.g dT into -dT smoothly (linearly) - - double HA,HB,dxmolnew[ncmax],Tnew,pnew,dlow,dhigh,hlow,hhigh,h_l,h_v; - //double ddq,ddl_l,ddv_v,ddx[ncmax],ddy[ncmax]; - - ENTHALdll (dt,ddl,dxmoll,h_l); - ENTHALdll (dt,ddv,dxmolv,h_v); - HA = 0.025*(h_v-h_l)+h_l; - HB = 0.075*(h_v-h_l)+h_l; - - //printf("hl = %f", h_l); - //printf("hv = %f", h_v); - - double DT,DP,DX,smooth,dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; - - DT=0.5; - DP=-25; - DX=0.002; - - if (dh < HA) { - // DT - //DT=DT; - Tnew= dt+DT; - //this function does not work? - //(t,p,z,Dl,Dv,x,y,q,ierr,herr) - //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (Tnew,ddl_l,ddx,h_l); - //ENTHALdll (Tnew,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); - TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddT_pX = (dlow-dd)/(DT); - dhdT_pX = (hlow-dh)/(DT); - // DP - //DP=DP; - pnew = dp+DP; - //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); - TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddP_TX = (dlow-dd)/(DP); - dhdP_TX = (hlow-dh)/(DP); - // DX - //DX = DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 - //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); - TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dlow-dd)/(DX); - dhdX_pT = (hlow-dh)/(DX); - } else if (dh > HB) { - // DT - DT = -DT; - Tnew= dt+DT; - //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (Tnew,ddl_l,ddx,h_l); - //ENTHALdll (Tnew,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); - TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddT_pX = (dhigh-dd)/(DT); - dhdT_pX = (hhigh-dh)/(DT); - // DP - DP = -DP; - pnew=dp+DP; - //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); - TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddP_TX = (dhigh-dd)/(DP); - dhdP_TX = (hhigh-dh)/(DP); - // DX - DX = -DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); - TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dhigh-dd)/(DX); - dhdX_pT = (hhigh-dh)/(DX); - } else { // something smooth - smooth=(dh-HA)/(HB-HA); - // DT - //DT = DT; - Tnew= dt+DT; - //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (Tnew,ddl_l,ddx,h_l); - //ENTHALdll (Tnew,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); - TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - DT=-DT; - Tnew= dt+DT; - //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (Tnew,ddl_l,ddx,h_l); - //ENTHALdll (Tnew,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); - TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddT_pX = (dlow-dd)/(-DT)*(1-smooth) + smooth*(dhigh-dd)/(DT); - dhdT_pX = (hlow-dh)/(-DT)*(1-smooth) + smooth*(hhigh-dh)/(DT); - // DP - //DP = DP; - pnew=dp+DP; - //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); - TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - DP = -DP; - pnew=dp+DP; - //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); - TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddP_TX = (dlow-dd)/(-DP)*(1-smooth) + smooth*(dhigh-dd)/(DP); - dhdP_TX = (hlow-dh)/(-DP)*(1-smooth) + smooth*(hhigh-dh)/(DP); - // DX - //DX = DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hlow = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); - TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - DX = -DX; - dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. - dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix - //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); - //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); - //ENTHALdll (dt,ddl_l,ddx,h_l); - //ENTHALdll (dt,ddv_v,ddy,h_v); - //hhigh = ddq*h_v + (1-ddq)*h_l; - if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); - TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); - dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); - dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); - } + // analytical derivatives of enthalpy: + ddhdT_p = dCp; + ddhdp_T = (1-dt*dbeta)/dd; - ddddh_p = dddT_pX/dhdT_pX; - ddddp_h = (dddP_TX*dhdT_pX-dhdP_TX*dddT_pX)/dhdT_pX; - ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; - } else { - printf("Both partial derivative calculation flags cannot be true.."); - } + // numerical derivatives wrt. independent mass fraction, + // NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; + double dnew,hnew; + //XMASSdll(dxmol,dxkgnew,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + TPFLSHdll(dt,dp,dxmolnew,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddX_pT = (dnew*dwmnew-dd*dwm)/1e-7; // this is on mass basis, due to the above mass change + ddhdX_pT = (hnew/dwmnew*1000-dh/dwm*1000)/1e-7; // this is on mass basis, due to the above mass change - /* - printf("dqmol %f\n", dqmol); - if (dwvap==noValue) - { - printf("dwm %f\n", dwm); - printf("dwvap %f\n", dwvap); - WMOLdll(dxmolv,dwvap); - dqmol = dqmol*dwvap/dwm; - printf("first dqmol %f\n", dqmol); - } else { - printf("dwm %f\n", dwm); - printf("dwvap %f\n", dwvap); - dqmol = dqmol*dwvap/dwm; - printf("second dqmol %f\n", dqmol); +// double n; +// double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax]; +// href[0] = 28945.714499977374; // ammoniaL +// href[1] = 45957.1914944204584; // water +// +// double delx=1e-7,delx2,R,dxmoln,dxmolp,t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; +// long im1=-1, i0=0, ip1=1; +// int i; +// +// for (n = 0; n < lnc; n++) { +// //double n=1;// derivative wrt component n +// +// for (i = 0; i < lnc; i++) { +// dxmoln[i] = dxmol[i]; +// dxmolp[i] = dxmol[i]; +// } +// dxmoln[n-1] = dxmoln[n-1] - delx; +// dxmolp[n-1] = dxmolp[n-1] + delx; +// +// // negative increment +// RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); +// pn = dd * R * dt * (1 + phi01); +// //hrn = R * t * (1 + phi10 + phi01); +// hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; +// +// // positive increment +// //RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); +// pp = dd * R * dt * (1 + phi01); +// //hrp = R * t * (1 + phi10 + phi01); +// hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; +// +// // derivatives.. +// dpdz_tv[n-1] = (pp - pn) / delx2; +// //dhrdxi1 = (hrp - hrn) / delx2; +// dhdz_tv[n-1] = (hp - hn) / delx2; +// } + + + + } else { // two-phase region, get derivative of density + + // numerical derivative wrt. Temperature: + double dnew,hnew,dtnew; + dtnew=dt+1e-4; + TPFLSHdll(dtnew,dp,dxmol,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddT_p = (dnew-dd)/1e-4; + ddhdT_p = (hnew-dh)/1e-4; + + // numerical derivative wrt. Pressure: + double dpnew=dp+1e-3; // this is a change in 1 Pa + TPFLSHdll(dt,dpnew,dxmol,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddp_T = (dnew-dd)/1e-3; // /1; + ddhdp_T = (hnew-dh)/1e-3; // /1; + + // numerical derivative for independent mass fraction + /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; + //XMASSdll(dxmol,dxkgnew,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + TPFLSHdll(dt,dp,dxmolnew,dnew,spare3,spare4,spare1,spare2,spare5,spare6,hnew,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + ddddX_pT = (dnew*dwmnew-dd*dwm)/1e-7; // this is on mass basis, due to the above mass change + ddhdX_pT = (hnew/dwmnew*1000-dh/dwm*1000)/1e-7; // this is on mass basis, due to the above mass change + } - printf("dqmol %f\n", dqmol); - */ + } else { + + if (dqmol < 0. || dqmol > 1.) { // single-phase region + if (debug) printf ("Using single-phase derivatives.\n"); + + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + + // analytical derivatives + ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; + ddddh_p = -dbeta*dd/dCp; + + + // numerical derivative for ddddzi + + double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz; + dpdT_zv = dbeta/dxkappa; + dpdv_Tz= -dd/dxkappa; + dhdT_vz = dCv+dbeta/(dd*dxkappa); + dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); + +/* + double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax],dvdz_ph[ncmax],ddddX_ph_tmp[ncmax]; + //href[0] = 28945.714499977374; // ammoniaL + //href[1] = 45957.1914944204584; // water + + href[0] = 8295.6883966232; //methane + + href[1] = 14873.1879732343; //ethane + + double delx=1e-7,delx2,R,dxmoln[ncmax],dxmolp[ncmax],t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; + long im1=-1, i0=0, ip1=1; + delx2=delx*2; + + for (int n = 1; n < lnc+1; n++) { + //double n=1;// derivative wrt component n + + for (int i = 0; i < lnc; i++) { + dxmoln[i] = dxmol[i]; + dxmolp[i] = dxmol[i]; + } + dxmoln[n-1] = dxmoln[n-1] - delx; + dxmolp[n-1] = dxmolp[n-1] + delx; + + // negative increment + RMIX2dll(dxmol, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); + tau = t0 / dt; + delta =dd / d0; + PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); + PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); + PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); + pn = dd * R * dt * (1 + phi01); + //hrn = R * t * (1 + phi10 + phi01); + hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; + + // positive increment + //RMIX2dll(dxmol, R); // R must be constant for some reason? + RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); + tau = t0 / dt; + delta =dd / d0; + PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); + PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); + PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); + pp = dd * R * dt * (1 + phi01); + //hrp = R * t * (1 + phi10 + phi01); + hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; + + // numerical derivatives.. + dpdz_tv[n-1] = (pp - pn) / delx2; + dhdz_tv[n-1] = (hp - hn) / delx2; + + // expression from jacobian matrix transformation + dvdz_ph[n-1] = (dpdT_zv*dhdz_tv[n-1] - dhdT_vz*dpdz_tv[n-1]) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); + ddddX_ph_tmp[n-1] = -dd*dd*dvdz_ph[n-1]; // this is still in refprop units, so X is moli/moltot.. + + } + + //printf("dhdz_tv[0] = %f\n",dhdz_tv[0]); + //printf("dhdz_tv[1] = %f\n",dhdz_tv[1]); + + double dxmolnew[ncmax],dwmnew[ncmax]; + dxmolnew[0] =1; + dxmolnew[1] =0; + WMOLdll(dxmolnew,dwmnew[0]); + dxmolnew[0] =0; + dxmolnew[1] =1; + WMOLdll(dxmolnew,dwmnew[1]); +// ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dxmol[0]/dxkg[0]*dwm; +// ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dxmol[1]/dxkg[1]*dwm; + //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*1/(dwmnew[0]/dwm)*dwm; + //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*1/(dwmnew[1]/dwm)*dwm; + //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dwm; + //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dwm; + + double dxdz1 = dwmnew[0]/dwm - dxmol[0]*dwmnew[0]*dwmnew[0]/(dwm*dwm); + double dxdz2 = dwmnew[1]/dwm - dxmol[1]*dwmnew[1]*dwmnew[1]/(dwm*dwm); + + //double ddmassddmol = dd*(dwmnew[0]*) + + //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*(dwmnew[0]*dxmol[1]*dwmnew[1]/(dwm*dwm))*dwm; + //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*(dwmnew[0]*dxmol[0]*dwmnew[1]/(dwm*dwm))*dwm; + + ddddX_ph = (ddddX_ph_tmp[0] - ddddX_ph_tmp[1])/(dxdz1+dxdz2)*dwm; + + // this does not work... + */ + + double dpdz_td,dhdz_td; + //double dxmolnew[ncmax],dwmnew; + double pnew,hnew; + double dvdz_ph; + + // numerical derivative for independent mass fraction + /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; + //XMASSdll(dxmol,dxkgnew,dwmnew); + dxkgnew[0] = dxkg[0]+1e-5; + dxkgnew[1] = dxkg[1]-1e-5; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + double din; + din=dd*dwm/dwmnew; + PRESSdll (dt,din,dxmolnew,pnew); + ENTHALdll (dt,din,dxmolnew,hnew); + + dpdz_td = (pnew-dp)/1e-5; + dhdz_td = (hnew/dwmnew-dh/dwm)*dwm/1e-5; + + // expression from jacobian matrix transformation + dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); + ddddX_ph = -dd*dd*dvdz_ph; + ddddX_ph = ddddX_ph*dwm; // this is already per X due to the above change in mass fraction and conversion.. + + + } else { // two-phase region, get derivative of density + + // These are not computed in two-phase! + dxkappa=noValue; + dbeta=noValue; + + if (PartialDersInputChoice==3) { // Using phX Analytical twophase derivatives + if (debug) printf ("Using Analytical twophase derivatives\n"); + + // // TODO the below analytical derivs are wrong since saturated liquid and vapor concentrations change along evaporation.. + + + /* j--phase flag: 1 = input x is liquid composition (bubble point) + 2 = input x is vapor composition (dew point) + 3 = input x is liquid composition (freezing point) + 4 = input x is vapor composition (sublimation point) + */ + + //compute saturated vapor state at const p + long kph2 = 2; + double dt_v,ddv_p,dCv_v,dCp_v,dwm_v,dxkappa_v,dbeta_v,h_v,s_v; + SATPdll(dp,dxmol,kph2,dt_v,spare3,ddv_p,spare2,spare1,lerr,errormsg,errormessagelength); + ENTHALdll(dt_v,ddv_p,dxmol,h_v); + //compute saturated liquid state at const p + long kph1 = 1; + double dt_l,ddl_p,dCv_l,dCp_l,dwm_l,dxkappa_l,dbeta_l,h_l,s_l; + SATPdll(dp,dxmol,kph1,dt_l,ddl_p,spare3,spare2,spare1,lerr,errormsg,errormessagelength); + ENTHALdll(dt_l,ddl_p,dxmol,h_l); + // compute partials + double dvdh_p,dTdp_clasius, dhdpL,dhdpV,dvdpL,dvdpV,dxdp_h,dvdp_h; + // compute drhodh_p + dvdh_p = (1/ddv_p - 1/ddl_p)/(h_v-h_l); + ddddh_p = -dd*dd*dvdh_p; + // get other sat props at const T,p,x + THERM2dll(dt, ddv, dxmolv, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + THERM2dll(dt, ddl, dxmoll, spare3, spare4, h_l, s_l, dCv_l, dCp_l, dwm_l,spare2, spare10, spare11, spare12, dxkappa_l, dbeta_l, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + //ddv_v = ddv; + //ddl_l = ddl; + // compute drhodp_h + //dTdp_clasius = (1/ddv - 1/ddl)/(s_v-s_l); + dTdp_clasius = dt*(1/ddv - 1/ddl)/(h_v-h_l); + dhdpL = 1/ddl*(1-dbeta_l*dt_l)+dCp_l*dTdp_clasius; + dhdpV = 1/ddv*(1-dbeta_v*dt_v)+dCp_v*dTdp_clasius; + dvdpL = dbeta_l*1/ddl*dTdp_clasius-dxkappa_l*1/ddl; + dvdpV = dbeta_v*1/ddv*dTdp_clasius-dxkappa_v*1/ddv; + dxdp_h = (dhdpL + dqmol * (dhdpV-dhdpL))/(h_l-h_v); + dvdp_h = dvdpL+dxdp_h*(1/ddv-1/ddl)+dqmol*(dvdpV-dvdpL); + ddddp_h = -dd*dd*dvdp_h; + + // analytical derivative for ddddzi + double dhdz_tp, dvdz_tp; + double dxkgv[ncmax],dwmv,dxkgl[ncmax],dwml; + XMASSdll(dxmolv,dxkgv,dwmv); + XMASSdll(dxmoll,dxkgl,dwml); + dhdz_tp = (h_v/dwmv*1000-h_l/dwml*1000)/(dxkgv[0]-dxkgl[0]); + dvdz_tp = (1/(ddv*dwmv)-1/(ddl*dwml))/(dxkgv[0]-dxkgl[0]); + dvdh_p = dvdh_p/dwm*dwm/1000; + ddddX_ph = -dd*dwm*dd*dwm*(-dvdh_p*dhdz_tp+dvdz_tp); + + //dhdz_tp = (h_v-h_l)/(dxmolv[0]-dxmoll[0]); + //dvdz_tp = (1/ddv_v-1/ddl_l)/(dxmolv[0]-dxmoll[0]); + //ddddX_ph = -dd*dd*(-dvdh_p*dhdz_tp+dvdz_tp); + + +// // numerical derivative for ddddzi, that ensures xmol is between 0 and 1 +// double HA,HB,smooth,DX,dxmolnew[ncmax],dlow,dhigh; +// HA = 0.925*(h_v-h_l)+h_l; +// HB = 0.975*(h_v-h_l)+h_l; +// +// /* +// // using PHFLSH to get numerical derivative ddddzi +// DX=0.005; +// if (dh < HA) { +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dlow-dd)/DX; +// } else if (dh > HB) { +// DX=-DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dhigh-dd)/DX; +// } else { +// smooth=(dh-HA)/(HB-HA); +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// PHFLSHdll(dp,dh,dxmolnew,spare14,dlow,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// PHFLSHdll(dp,dh,dxmolnew,spare14,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); +// ddddX_ph = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); +// } +// */ +// +// // Using TPFLSH to get numerical derivative ddddzi +// double dhdT_pX, dddT_pX,hlow,hhigh,dddX_pT,dhdX_pT; +// +// dhdT_pX = (h_v - h_l)/(dt_v-dt_l); +// //dvdT_p = (1/ddv_v - 1/ddl_l)/(dt_v-dt_l); +// dddT_pX = -dd*dd*(1/ddv_v - 1/ddl_l)/(dt_v-dt_l); +// +// DX=0.0025; +// if (dh < HA) { +// //DX = DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 +// TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dlow-dd)/(DX); +// dhdX_pT = (hlow-dh)/(DX); +// } else if (dh > HB) { +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dhigh-dd)/(DX); +// dhdX_pT = (hhigh-dh)/(DX); +// } else { // something smooth +// smooth=(dh-HA)/(HB-HA); +// //DX = DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// DX = -DX; +// dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. +// dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix +// TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); +// dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); +// dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); +// } +// ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + + + } else if (PartialDersInputChoice==2) { // Using phX Numerical twophase derivatives + if (debug) printf ("Using Numerical two phase derivatives\n"); + + // in the following HA and HB are points in two-phase, where the numerical derivative changes "the sign of change", e.g dT into -dT smoothly (linearly) + + //using PHFLSH to get numerical derivative ddddzi + double dnew,dpnew; + dpnew = dp +1e-3; // change in 1 Pa + PHFLSHdll(dpnew,dh,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddp_h = (dnew-dd)/1e-3; + + double dhnew; + dhnew = dh +(1*dwm/1000); // change in 1 J/kg*K + PHFLSHdll(dp,dhnew,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddh_p = (dnew-dd)/(1*dwm/1000); + + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; +// XMASSdll(dxmol,dxkg,dwmnew); + dxkgnew[0] = dxkg[0]+1e-5; + dxkgnew[1] = dxkg[1]-1e-5; + XMOLEdll(dxkgnew,dxmolnew,dwmnew); + PHFLSHdll(dp,dh,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dnew*dwm-dd*dwm)/1e-5; // mass basis + +/* + double HA,HB,dxmolnew[ncmax],Tnew,pnew,dlow,dhigh,hlow,hhigh,h_l,h_v; + //double ddq,ddl_l,ddv_v,ddx[ncmax],ddy[ncmax]; + + ENTHALdll (dt,ddl,dxmoll,h_l); + ENTHALdll (dt,ddv,dxmolv,h_v); + HA = 0.025*(h_v-h_l)+h_l; + HB = 0.075*(h_v-h_l)+h_l; + + double DT,DP,DX,smooth,dddT_pX,dhdT_pX,dddP_TX,dhdP_TX,dddX_pT,dhdX_pT; + + DT=0.5; + DP=-25; + DX=0.002; + + if (dh < HA) { + // DT + //DT=DT; + Tnew= dt+DT; + //this function does not work? + //(t,p,z,Dl,Dv,x,y,q,ierr,herr) + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(DT); + dhdT_pX = (hlow-dh)/(DT); + // DP + //DP=DP; + pnew = dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(DP); + dhdP_TX = (hlow-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix, but refprop needs sum(x)=1 + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + double dwmnew; + WMOLdll(dxmolnew,dwmnew); + dddX_pT = (dlow/dwmnew-dd/dwm)*dwm/(DX); + dhdX_pT = (hlow/dwmnew-dh/dwm)*dwm/(DX); + } else if (dh > HB) { + // DT + DT = -DT; + Tnew= dt+DT; + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dhigh-dd)/(DT); + dhdT_pX = (hhigh-dh)/(DT); + // DP + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dhigh-dd)/(DP); + dhdP_TX = (hhigh-dh)/(DP); + // DX + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + double dwmnew; + WMOLdll(dxmolnew,dwmnew); + dddX_pT = (dhigh/dwmnew-dd/dwm)*dwm/(DX); + dhdX_pT = (hhigh/dwmnew-dh/dwm)*dwm/(DX); + } else { // something smooth + smooth=(dh-HA)/(HB-HA); + // DT + //DT = DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DT=-DT; + Tnew= dt+DT; + //TPFL2dll (Tnew,dp,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (Tnew,ddl_l,ddx,h_l); + //ENTHALdll (Tnew,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",Tnew,dp,dxmol[0]); + TPFLSHdll(Tnew,dp,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddT_pX = (dlow-dd)/(-DT)*(1-smooth) + smooth*(dhigh-dd)/(DT); + dhdT_pX = (hlow-dh)/(-DT)*(1-smooth) + smooth*(hhigh-dh)/(DT); + // DP + //DP = DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DP = -DP; + pnew=dp+DP; + //TPFL2dll (dt,pnew,dxmol,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,pnew,dxmol[0]); + TPFLSHdll(dt,pnew,dxmol,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddP_TX = (dlow-dd)/(-DP)*(1-smooth) + smooth*(dhigh-dd)/(DP); + dhdP_TX = (hlow-dh)/(-DP)*(1-smooth) + smooth*(hhigh-dh)/(DP); + // DX + //DX = DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dlow = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hlow = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dlow,spare3,spare4,spare1,spare2,spare5,spare6,hlow,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + DX = -DX; + dxmolnew[0]=dxmol[0]+DX; // Be carefull when comparing.. keeping X2 const is not the same as keeping z2 const ??? or.. + dxmolnew[1]=dxmol[1]-DX; // This is wrong as you may show that x2 should be eheld constant for an ideal gas mix + //TPFL2dll (dt,dp,dxmolnew,ddl_l,ddv_v,ddx,ddy,ddq,lerr,errormsg,errormessagelength); + //dhigh = 1/(ddq/ddv_v + (1-ddq)/ddl_l); + //ENTHALdll (dt,ddl_l,ddx,h_l); + //ENTHALdll (dt,ddv_v,ddy,h_v); + //hhigh = ddq*h_v + (1-ddq)*h_l; + if (debug) printf("Calling TPFLSHdll with T=%f and P=%f. and xmol[0]=%f\n",dt,dp,dxmolnew[0]); + TPFLSHdll(dt,dp,dxmolnew,dhigh,spare3,spare4,spare1,spare2,spare5,spare6,hhigh,spare7,spare8,spare11,spare12,lerr,errormsg,errormessagelength); + dddX_pT = (dlow-dd)/(-DX)*(1-smooth) + smooth*(dhigh-dd)/(DX); + dhdX_pT = (hlow-dh)/(-DX)*(1-smooth) + smooth*(hhigh-dh)/(DX); + } + + ddddh_p = dddT_pX/dhdT_pX; + ddddp_h = (dddP_TX*dhdT_pX-dhdP_TX*dddT_pX)/dhdT_pX; + ddddX_ph = -(dddT_pX*dhdX_pT-dhdT_pX*dddX_pT)/dhdT_pX; + ddddX_ph = ddddX_ph*dwm; +*/ + + } + + + } } @@ -1838,6 +1924,11 @@ int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ int updateProps(double *props, long lerr){ + + double dxlkg[ncmax], dxvkg[ncmax]; + XMASSdll(dxmoll,dxlkg,dwliq); + XMASSdll(dxmolv,dxvkg,dwvap); + //ASSIGN VALUES TO RETURN ARRAY props[0] = lerr;//error code props[1] = getP_modelica(); //pressure in Pa @@ -1856,11 +1947,6 @@ int updateProps(double *props, long lerr){ props[14] = getWML_modelica(); props[15] = getWMV_modelica(); - double dxlkg[ncmax], dxvkg[ncmax]; - - XMASSdll(dxmoll,dxlkg,dwliq); - XMASSdll(dxmolv,dxvkg,dwvap); - for (int dim=0; dim1) flushConstants(); + else flushProperties(); + if (debug) printf("Loading a new state, flushed state. \n"); + + +/* //TODO Is this really nescesary? I think the possibility of dymola calling with same state twice is almost none (it will call for other states to compute, in between).. + bool knownState = isState(var1,val1,var2,val2,dxmoltmp,lnc); // dummies to force recalculation double result = getValue(out); bool valueExists = (result!=noValue); @@ -2007,7 +2132,7 @@ OUTPUT return result; } } - +*/ /* * If we get to this point, the requested value was not part of an earlier @@ -2252,10 +2377,21 @@ OUTPUT updateProps(props, lerr); - if (calcTwoPhaseNumDers || calcTwoPhasePsuedoAnalDers) { + if (PartialDersInputChoice!=1) { int outVal = ders_REFPROP(ders,errormsg,debug); if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); + } else { // compute beta and kappa anyway in single-phase region + if (dqmol < 0. || dqmol > 1.) { + if (debug) printf("Calling THERM3 with T=%f and rho=%f.\n",dt,dd); + double spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12; + THERM3dll (dt,dd,dxmol,dxkappa,dbeta,spare5,spare6,spare7,spare8,spare9,spare10,spare11,spare12); + } else { + dxkappa=noValue; //TODO why is this not flushed? + dbeta=noValue; + } + updateDers(ders, lerr); } + if (calcTrans) { int outVal = trns_REFPROP(trns,errormsg,debug); if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); @@ -2352,7 +2488,7 @@ OUTPUT bool knownState = false; // dummies to force recalculation bool valueExists = false; - +// TODO This is out-commented for props_refprop function // TODO - why do we want to flush properties for the setState functions here when setsat is called? if (!knownState) { if (lnc>1) flushConstants(); @@ -2372,7 +2508,7 @@ OUTPUT */ // Convert mass-based composition to mole fractions and set molecular weight. - double* dxkg; +// double* dxkg; dxkg = x; XMOLEdll(dxkg,dxmolsat,dwmsat); // dwm = dwm / 1000; // from g/mol to kg/mol //keep refprop units.. diff --git a/_wrapper/src/refprop_wrapper.h b/_wrapper/src/refprop_wrapper.h index a3ed490..da56c9a 100644 --- a/_wrapper/src/refprop_wrapper.h +++ b/_wrapper/src/refprop_wrapper.h @@ -42,7 +42,7 @@ #if defined(__cplusplus) extern "C" { #endif // __cplusplus - EXPCONV double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport, int calcTwoPhaseNumericalDerivatives, int calcTwoPhasePsuedoAnalyticalDerivatives); //declaration; + EXPCONV double props_REFPROP(char* what, char* statevars, char* fluidnames, double *ders, double *trns, double *props, double statevar1, double statevar2, double* x, int phase, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport, int partialDersInputChoice); //declaration; EXPCONV double satprops_REFPROP(char* what, char* statevar, char* fluidnames, double *satprops, double statevarval, double Tsurft, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE,int calcTransport); //declaration; #if defined(__cplusplus) } From 9176186be32faf5557e2fac5f2d771f124d2c643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Wed, 15 Jan 2014 08:40:12 +0100 Subject: [PATCH 50/57] There are four ways to compute partial derivatives determined by "partialDersInputChoice", an input the setState_phX and setState_pTX functions: 1: none (default) 2: partial derivatives of d wrt p,h,X In two-phase region: numerical differentiation for all derivatives In single phase region: dddX is numerical and others are analytical 3: partial derivatives of d wrt p,h,X In two-phase region: pseudo analytical (similar procedure as pure fluid - they give almost same result as method 2, and with less CPU effort). In single phase region: dddX is numerical and others are analytical 4: partial derivatives of d and h wrt p,T,X In two-phase region: numerical differentiation for all derivatives In single phase region: dddX is numerical and others are analytical The second and fourth methods compare exactly with stepping forward in u,d,X (the baseline with most CPU effort, due to tedious iteration in property functions at every time step, u,d,X -> T,p,h etc.). Method 4 is guicker in the two-phase region compared to method 2, because T and P are equilibrium quantities, and thus the most typical flash function.. Method 3 is fastest, but does not give correct dynamics and will cause mass convervation to fail. Note that the dddX derivative is the difference in dddX1|X2=const-dddX2|X1=const The partials have only been tested for binary mixtures.. --- Interfaces/PartialMixtureTwoPhaseMedium.mo | 7 +- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 35 +++ _wrapper/cpptest/cpp_wrapped2.cpp | 4 +- _wrapper/src/refprop_wrapper.cpp | 259 +++++++++++---------- _wrapper/src/refprop_wrapper.lib | Bin 0 -> 269444 bytes 5 files changed, 179 insertions(+), 126 deletions(-) create mode 100644 _wrapper/src/refprop_wrapper.lib diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index 4620b07..aa7c920 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -81,6 +81,7 @@ end ThermodynamicState; replaceable record SaturationProperties "Saturation properties of two phase medium" extends Modelica.Icons.Record; + Temperature Tl(min=1e-8) "saturation temperature at bubble line"; Temperature Tv(min=1e-8) "saturation temperature at dew line"; AbsolutePressure pl(min=1e-8) "saturation pressure at bubble line"; @@ -102,6 +103,8 @@ end ThermodynamicState; // MolarMass MMv "molar mass at dew line (for pressure ps)"; // MassFraction Xl[nX] "Mass fractions of liquid phase"; // MassFraction Xv[nX] "Mass fractions of gaseous phase"; + AbsolutePressure psat annotation(HideResult=true); + Temperature Tsat annotation(HideResult=true); end SaturationProperties; redeclare replaceable model extends BaseProperties( @@ -894,7 +897,7 @@ end temperature; replaceable function vapourQuality "Return vapour quality" input ThermodynamicState state "Thermodynamic state record"; - output MassFraction q "Vapour quality"; + output MassFraction x "Vapour quality"; protected constant SpecificEnthalpy eps = 1e-8; algorithm @@ -905,7 +908,7 @@ end temperature; // pressure(state), state.X)) - bubbleEnthalpy( // setSat_pX( // pressure(state), state.X)) + eps), 0), 1); - q := state.q; + x := state.q; annotation(Documentation(info="")); end vapourQuality; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 0b53709..1e51374 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -722,6 +722,8 @@ end ThermodynamicState; assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); sat := SaturationProperties( + psat=99999, + Tsat=99999, Tl=satprops[2], Tv=satprops[3], pl=satprops[4], @@ -1967,6 +1969,39 @@ end ThermodynamicState; s_out := s_out + delimiter + s_in[i]; end for; end StrJoin; + + replaceable function setSat_p + "Return saturation property record from pressure" + extends Modelica.Icons.Function; + input AbsolutePressure p "pressure"; + input MassFraction X[nX] "Mass fractions"; + input Real Tsurft=0 + "additional temperature for surface tension function, in case of setSat_pX"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "p", + p, + X, + Tsurft, + calcTransport); + end setSat_p; + + replaceable function setSat_T + "Return saturation property record from temperature" + extends Modelica.Icons.Function; + input Temperature T "temperature"; + input MassFraction X[nX] "Mass fractions"; + input Boolean calcTransport=false; + output SaturationProperties sat "saturation property record"; + algorithm + sat := setSat( + "t", + T, + X, + calcTransport=calcTransport); + end setSat_T; annotation (Documentation(info="

REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. diff --git a/_wrapper/cpptest/cpp_wrapped2.cpp b/_wrapper/cpptest/cpp_wrapped2.cpp index 4fd2029..36f2d04 100644 --- a/_wrapper/cpptest/cpp_wrapped2.cpp +++ b/_wrapper/cpptest/cpp_wrapped2.cpp @@ -313,9 +313,9 @@ int main(int argc, char* argv[]){ */ //double dpdxi12; - double dn=d*wm/wmn; // mass density should be kept constant even through we change concentration.. + double dn=d;//*wm/wmn; // mass density should be kept constant even through we change concentration.. PRESSdll(t,dn,xnn,pn); - double dp=d*wm/wmp; // mass density should be kept constant even through we change concentration.. + double dp=d;//*wm/wmp; // mass density should be kept constant even through we change concentration.. PRESSdll(t,dp,xpp,pp); dpdxi12 = (pp - pn) / (delx2); diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index aff47f8..03e838a 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -1366,126 +1366,137 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ ddddp_h = (-dt*dbeta*dbeta + dbeta + dxkappa*dd*dCp)/dCp; ddddh_p = -dbeta*dd/dCp; - - // numerical derivative for ddddzi - - double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz; - dpdT_zv = dbeta/dxkappa; - dpdv_Tz= -dd/dxkappa; - dhdT_vz = dCv+dbeta/(dd*dxkappa); - dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); - -/* - double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax],dvdz_ph[ncmax],ddddX_ph_tmp[ncmax]; - //href[0] = 28945.714499977374; // ammoniaL - //href[1] = 45957.1914944204584; // water - - href[0] = 8295.6883966232; //methane - - href[1] = 14873.1879732343; //ethane - - double delx=1e-7,delx2,R,dxmoln[ncmax],dxmolp[ncmax],t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; - long im1=-1, i0=0, ip1=1; - delx2=delx*2; - - for (int n = 1; n < lnc+1; n++) { - //double n=1;// derivative wrt component n - - for (int i = 0; i < lnc; i++) { - dxmoln[i] = dxmol[i]; - dxmolp[i] = dxmol[i]; - } - dxmoln[n-1] = dxmoln[n-1] - delx; - dxmolp[n-1] = dxmolp[n-1] + delx; - - // negative increment - RMIX2dll(dxmol, R); // R must be constant for some reason? - RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); - tau = t0 / dt; - delta =dd / d0; - PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); - PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); - PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); - pn = dd * R * dt * (1 + phi01); - //hrn = R * t * (1 + phi10 + phi01); - hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; - - // positive increment - //RMIX2dll(dxmol, R); // R must be constant for some reason? - RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); - tau = t0 / dt; - delta =dd / d0; - PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); - PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); - PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); - pp = dd * R * dt * (1 + phi01); - //hrp = R * t * (1 + phi10 + phi01); - hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; - - // numerical derivatives.. - dpdz_tv[n-1] = (pp - pn) / delx2; - dhdz_tv[n-1] = (hp - hn) / delx2; - - // expression from jacobian matrix transformation - dvdz_ph[n-1] = (dpdT_zv*dhdz_tv[n-1] - dhdT_vz*dpdz_tv[n-1]) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); - ddddX_ph_tmp[n-1] = -dd*dd*dvdz_ph[n-1]; // this is still in refprop units, so X is moli/moltot.. - - } - - //printf("dhdz_tv[0] = %f\n",dhdz_tv[0]); - //printf("dhdz_tv[1] = %f\n",dhdz_tv[1]); - - double dxmolnew[ncmax],dwmnew[ncmax]; - dxmolnew[0] =1; - dxmolnew[1] =0; - WMOLdll(dxmolnew,dwmnew[0]); - dxmolnew[0] =0; - dxmolnew[1] =1; - WMOLdll(dxmolnew,dwmnew[1]); -// ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dxmol[0]/dxkg[0]*dwm; -// ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dxmol[1]/dxkg[1]*dwm; - //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*1/(dwmnew[0]/dwm)*dwm; - //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*1/(dwmnew[1]/dwm)*dwm; - //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dwm; - //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dwm; - - double dxdz1 = dwmnew[0]/dwm - dxmol[0]*dwmnew[0]*dwmnew[0]/(dwm*dwm); - double dxdz2 = dwmnew[1]/dwm - dxmol[1]*dwmnew[1]*dwmnew[1]/(dwm*dwm); - - //double ddmassddmol = dd*(dwmnew[0]*) - - //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*(dwmnew[0]*dxmol[1]*dwmnew[1]/(dwm*dwm))*dwm; - //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*(dwmnew[0]*dxmol[0]*dwmnew[1]/(dwm*dwm))*dwm; - - ddddX_ph = (ddddX_ph_tmp[0] - ddddX_ph_tmp[1])/(dxdz1+dxdz2)*dwm; - - // this does not work... - */ - - double dpdz_td,dhdz_td; - //double dxmolnew[ncmax],dwmnew; - double pnew,hnew; - double dvdz_ph; - - // numerical derivative for independent mass fraction - /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ - double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; - //XMASSdll(dxmol,dxkgnew,dwmnew); - dxkgnew[0] = dxkg[0]+1e-5; - dxkgnew[1] = dxkg[1]-1e-5; + //using PHFLSH to get numerical derivative ddddX_ph + double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew, dnew; +// XMASSdll(dxmol,dxkg,dwmnew); + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; XMOLEdll(dxkgnew,dxmolnew,dwmnew); - double din; - din=dd*dwm/dwmnew; - PRESSdll (dt,din,dxmolnew,pnew); - ENTHALdll (dt,din,dxmolnew,hnew); + double dhin = dh*dwmnew/dwm; // this is needed because h in mass basis is constant.. + PHFLSHdll(dp,dhin,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dnew*dwmnew-dd*dwm)/1e-7; // mass basis - dpdz_td = (pnew-dp)/1e-5; - dhdz_td = (hnew/dwmnew-dh/dwm)*dwm/1e-5; - // expression from jacobian matrix transformation - dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); - ddddX_ph = -dd*dd*dvdz_ph; - ddddX_ph = ddddX_ph*dwm; // this is already per X due to the above change in mass fraction and conversion.. +// // numerical derivative for ddddzi +// +// double dpdT_zv,dpdv_Tz,dhdT_vz,dhdv_Tz; +// dpdT_zv = dbeta/dxkappa; +// dpdv_Tz= -dd/dxkappa; +// dhdT_vz = dCv+dbeta/(dd*dxkappa); +// dhdv_Tz = (dt*dbeta/dxkappa - 1/dxkappa); +// +///* +// double href[ncmax],dpdz_tv[ncmax],dhdz_tv[ncmax],dvdz_ph[ncmax],ddddX_ph_tmp[ncmax]; +// //href[0] = 28945.714499977374; // ammoniaL +// //href[1] = 45957.1914944204584; // water +// +// href[0] = 8295.6883966232; //methane +// +// href[1] = 14873.1879732343; //ethane +// +// double delx=1e-7,delx2,R,dxmoln[ncmax],dxmolp[ncmax],t0,d0,tau,delta,phi01,phi10,phig10,pn,hn,pp,hp; +// long im1=-1, i0=0, ip1=1; +// delx2=delx*2; +// +// for (int n = 1; n < lnc+1; n++) { +// //double n=1;// derivative wrt component n +// +// for (int i = 0; i < lnc; i++) { +// dxmoln[i] = dxmol[i]; +// dxmolp[i] = dxmol[i]; +// } +// dxmoln[n-1] = dxmoln[n-1] - delx; +// dxmolp[n-1] = dxmolp[n-1] + delx; +// +// // negative increment +// RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmoln,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmoln, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmoln, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmoln, phig10); +// pn = dd * R * dt * (1 + phi01); +// //hrn = R * t * (1 + phi10 + phi01); +// hn = R * dt * (1 + phig10 + phi10 + phi01) + dxmoln[0]*href[0] + dxmoln[1]*href[1];; +// +// // positive increment +// //RMIX2dll(dxmol, R); // R must be constant for some reason? +// RDXHMXdll(&im1,&i0,&i0,dxmolp,t0,d0,lerr,errormsg,errormessagelength); +// tau = t0 / dt; +// delta =dd / d0; +// PHIXdll(&i0,&ip1, tau, delta, dxmolp, phi01); +// PHIXdll(&ip1,&i0, tau, delta, dxmolp, phi10); +// PHI0dll(&ip1, &i0, dt, dd, dxmolp, phig10); +// pp = dd * R * dt * (1 + phi01); +// //hrp = R * t * (1 + phi10 + phi01); +// hp = R * dt * (1 + phig10 + phi10 + phi01) + dxmolp[0]*href[0] + dxmolp[1]*href[1];; +// +// // numerical derivatives.. +// dpdz_tv[n-1] = (pp - pn) / delx2; +// dhdz_tv[n-1] = (hp - hn) / delx2; +// +// // expression from jacobian matrix transformation +// dvdz_ph[n-1] = (dpdT_zv*dhdz_tv[n-1] - dhdT_vz*dpdz_tv[n-1]) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); +// ddddX_ph_tmp[n-1] = -dd*dd*dvdz_ph[n-1]; // this is still in refprop units, so X is moli/moltot.. +// +// } +// +// //printf("dhdz_tv[0] = %f\n",dhdz_tv[0]); +// //printf("dhdz_tv[1] = %f\n",dhdz_tv[1]); +// +// double dxmolnew[ncmax],dwmnew[ncmax]; +// dxmolnew[0] =1; +// dxmolnew[1] =0; +// WMOLdll(dxmolnew,dwmnew[0]); +// dxmolnew[0] =0; +// dxmolnew[1] =1; +// WMOLdll(dxmolnew,dwmnew[1]); +//// ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dxmol[0]/dxkg[0]*dwm; +//// ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dxmol[1]/dxkg[1]*dwm; +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*1/(dwmnew[0]/dwm)*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*1/(dwmnew[1]/dwm)*dwm; +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*dwm; +// +// double dxdz1 = dwmnew[0]/dwm - dxmol[0]*dwmnew[0]*dwmnew[0]/(dwm*dwm); +// double dxdz2 = dwmnew[1]/dwm - dxmol[1]*dwmnew[1]*dwmnew[1]/(dwm*dwm); +// +// //double ddmassddmol = dd*(dwmnew[0]*) +// +// //ddddX_ph_tmp[0] = ddddX_ph_tmp[0]*(dwmnew[0]*dxmol[1]*dwmnew[1]/(dwm*dwm))*dwm; +// //ddddX_ph_tmp[1] = ddddX_ph_tmp[1]*(dwmnew[0]*dxmol[0]*dwmnew[1]/(dwm*dwm))*dwm; +// +// ddddX_ph = (ddddX_ph_tmp[0] - ddddX_ph_tmp[1])/(dxdz1+dxdz2)*dwm; +// +// // this does not work... +// */ +// +// double dpdz_td,dhdz_td; +// //double dxmolnew[ncmax],dwmnew; +// double pnew,hnew; +// double dvdz_ph; +// +// // numerical derivative for independent mass fraction +// /* NOTE THAT IT IS DIFFICULT TO CHANGE FROM MOLE TO MASS BASIS, WHEN PERFORMING A NUMERICAL DERIVATIVE wrt composition. I DID NOT SUCCEED */ +// double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; +// //XMASSdll(dxmol,dxkgnew,dwmnew); +// dxkgnew[0] = dxkg[0]+1e-5; +// dxkgnew[1] = dxkg[1]-1e-5; +// XMOLEdll(dxkgnew,dxmolnew,dwmnew); +// double din; +// din=dd*dwm/dwmnew; +// PRESSdll (dt,din,dxmolnew,pnew); +// ENTHALdll (dt,din,dxmolnew,hnew); +// +// dpdz_td = (pnew-dp)/1e-5; +// dhdz_td = (hnew/dwmnew-dh/dwm)*dwm/1e-5; +// +// // expression from jacobian matrix transformation +// dvdz_ph = -(dpdT_zv*dhdz_td - dhdT_vz*dpdz_td) / (dpdT_zv*dhdv_Tz - dhdT_vz*dpdv_Tz); // the minus in front comes from ders wrt z is a change in both concentrations +// ddddX_ph = -dd*dd*dvdz_ph; +// ddddX_ph = ddddX_ph*dwm; // this is already per X due to the above change in mass fraction and conversion.. + } else { // two-phase region, get derivative of density @@ -1627,24 +1638,28 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ // in the following HA and HB are points in two-phase, where the numerical derivative changes "the sign of change", e.g dT into -dT smoothly (linearly) - //using PHFLSH to get numerical derivative ddddzi + //using PHFLSH to get numerical derivative ddddp_h double dnew,dpnew; dpnew = dp +1e-3; // change in 1 Pa PHFLSHdll(dpnew,dh,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); ddddp_h = (dnew-dd)/1e-3; + //using PHFLSH to get numerical derivative ddddh_p double dhnew; dhnew = dh +(1*dwm/1000); // change in 1 J/kg*K PHFLSHdll(dp,dhnew,dxmol,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); ddddh_p = (dnew-dd)/(1*dwm/1000); + + //using PHFLSH to get numerical derivative ddddX_ph double dxmolnew[ncmax], dxkgnew[ncmax], dwmnew; // XMASSdll(dxmol,dxkg,dwmnew); - dxkgnew[0] = dxkg[0]+1e-5; - dxkgnew[1] = dxkg[1]-1e-5; + dxkgnew[0] = dxkg[0]+1e-7; + dxkgnew[1] = dxkg[1]-1e-7; XMOLEdll(dxkgnew,dxmolnew,dwmnew); - PHFLSHdll(dp,dh,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); - ddddX_ph = (dnew*dwm-dd*dwm)/1e-5; // mass basis + double dhin = dh*dwmnew/dwm; // this is needed because h in mass basis is constant.. + PHFLSHdll(dp,dhin,dxmolnew,spare14,dnew,spare3,spare4,spare1,spare2,spare5,spare6,spare13,spare7,spare8,spare11,lerr,errormsg,errormessagelength); + ddddX_ph = (dnew*dwmnew-dd*dwm)/1e-7; // mass basis /* double HA,HB,dxmolnew[ncmax],Tnew,pnew,dlow,dhigh,hlow,hhigh,h_l,h_v; diff --git a/_wrapper/src/refprop_wrapper.lib b/_wrapper/src/refprop_wrapper.lib new file mode 100644 index 0000000000000000000000000000000000000000..edd941b2c6a8ce8ec40008a1ce42387f33d29a67 GIT binary patch literal 269444 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

*6!-489A~9+O&c8;ECUq5$G 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 ul4!^;{*t^1UJKck= Date: Mon, 27 Jan 2014 13:24:39 +0100 Subject: [PATCH 51/57] Some models that test partial derivatives, and compare state transformations against d,u, states.. --- Interfaces/PartialMixtureTwoPhaseMedium.mo | 2 +- Testers/NH3Water_MUXvsPHXvsPTX.mo | 545 +++++++++++++++++++++ Testers/NH3_Water_setStateModel.mo | 3 +- readme.md | 29 +- 4 files changed, 574 insertions(+), 5 deletions(-) create mode 100644 Testers/NH3Water_MUXvsPHXvsPTX.mo diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index aa7c920..f45cd16 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -930,7 +930,7 @@ type DerDerPressureByTemperatureByDensity = Real (unit="(m2)/(s2.K)"); type DerEnthalpyByDensity = Real (unit="J.m3/kg"); //type DerEnthalpyByPressure = Real (unit="J.m.s2/kg"); -type DerEnthalpyByTemperature = Real (unit="J/K"); +type DerEnthalpyByTemperature = Real (unit="J/(kg.K)"); annotation(Documentation(info="

PartialMixtureTwoPhaseMedium

diff --git a/Testers/NH3Water_MUXvsPHXvsPTX.mo b/Testers/NH3Water_MUXvsPHXvsPTX.mo new file mode 100644 index 0000000..e009705 --- /dev/null +++ b/Testers/NH3Water_MUXvsPHXvsPTX.mo @@ -0,0 +1,545 @@ +within REFPROP2Modelica.Testers; +package NH3Water_MUXvsPHXvsPTX + +model Volume_MUX "NH3 Water" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start = Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u(start = hstart-pstart/Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); +// Real X1(start=X1start); + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=400); + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + +Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + +equation + // Mass conservation + V * der(d) = port.m_flow; + // species conservation + V * (X[1]*der(d) + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(u) + u*der(d)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // Thermodynamic properties + state = Medium.setState_dTX(d,T,X); +// sat = Medium.setSat_pX(p,X[:]); +// u = Medium.specificInternalEnergy(state); +u = h - p/d; +//T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); +// d = Medium.density(state); + p = Medium.pressure(state); + +// port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; +// X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); +end Volume_MUX; + +model Volume_phX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d; + Medium.SpecificInternalEnergy u; +// Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T; + + Real dddt; +// Real dhdt; +// Real dddX[Medium.nX]; +// Real dddX_num; +// Real dddX_num_check; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + +Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + +equation + // derivative transformations + dddt = Medium.density_derh_p(state)*der(h) + Medium.density_derp_h(state)*der(p) + state.dddX_ph*der(X[1]); + // dddX = Medium.density_derX(state); + // dhdt = Medium.h_TX_der(T=T,X=X,dT=der(T),dX={der(X[1]),-der(X[1])}) "h is function of T and X only... and not p"; + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(h) + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + +// der(u)=0; +// der(d)=0; +// der(X1)=0; + +// // Thermodynamic properties +// state = Medium.setState_phX(p,h,X); +// sat = Medium.setSat_pX(p,X[:]); +// u = Medium.specificInternalEnergy(state); +// T = Medium.temperature(state); +// h = Medium.specificEnthalpy(state); +// d = Medium.density(state); +// p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_phX(p,h,X,partialDersInputChoice=3); +// sat = Medium.setSat_pX(p,X[:]); +// u = Medium.specificInternalEnergy(state); +u = h - p/d; + T = Medium.temperature(state); +// h = Medium.specificEnthalpy(state); + d = Medium.density(state); +// p = Medium.pressure(state); + +// port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; +// X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + +// additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + +// dddX_num = (Medium.density(state_dX)-d)/0.0001; +// dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); +end Volume_phX; + +model Volume_pTX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start=Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u; +// Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=Medium.temperature(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + + Real dddt; + Real dhdt; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + +Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + +equation + // derivative transformations + dddt = state.dddT_pX*der(T) + state.dddp_TX*der(p) + state.dddX_pT*der(X[1]); + dhdt = state.dhdT_pX*der(T) + state.dhdp_TX*der(p) + state.dhdX_pT*der(X[1]); + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*dhdt + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + +// der(u)=0; +// der(d)=0; +// der(X1)=0; + +// // Thermodynamic properties +// state = Medium.setState_phX(p,h,X); +// sat = Medium.setSat_pX(p,X[:]); +// u = Medium.specificInternalEnergy(state); +// T = Medium.temperature(state); +// h = Medium.specificEnthalpy(state); +// d = Medium.density(state); +// p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_pTX(p,T,X,partialDersInputChoice=4); +// sat = Medium.setSat_pX(p,X[:]); +// u = Medium.specificInternalEnergy(state); +u = h - p/d; +// T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); + d = Medium.density(state); +// p = Medium.pressure(state); + +// port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; +// X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + +// additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + +// dddX_num = (Medium.density(state_dX)-d)/0.0001; +// dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); +end Volume_pTX; + + +model system_MUX_sp + + Volume_MUX volume(V=0.01, hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); +equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); +end system_MUX_sp; + +model system_MUX_tp + + Volume_MUX volume(V=0.01, hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); +equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); +end system_MUX_tp; + +model system_phX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + V=0.01, + hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); +equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); +end system_phX_sp; + +model system_phX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + V=0.01, + hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); +equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); +end system_phX_tp; + +model system_pTX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=3000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=3000e3) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); +equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); +end system_pTX_sp; + +model system_pTX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=2000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=1500e3) + annotation (Placement(transformation(extent={{-38,-10},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); +equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20.4,1},{32,1},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-27,7.6},{-18,7.6},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); +end system_pTX_tp; + + +end NH3Water_MUXvsPHXvsPTX; diff --git a/Testers/NH3_Water_setStateModel.mo b/Testers/NH3_Water_setStateModel.mo index a94e25d..92ef85b 100644 --- a/Testers/NH3_Water_setStateModel.mo +++ b/Testers/NH3_Water_setStateModel.mo @@ -27,9 +27,8 @@ equation h=3e5 + time*25e5; X={0.5,0.5}; - state = Medium.setState_phX(p,h,X,calcTransport=true,partialDersInputChoice=3); + state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); q = Medium.vapourQuality(state); - d = Medium.density(state); dddh_pX = Medium.density_derh_p(state); diff --git a/readme.md b/readme.md index 4aafdc5..f496a59 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ #Welcome to REFPROP2Modelica! -This piece of software enables the user to access the Refprop fluid property database from within Modelica. Even though the code base is not very mature yet, this package seems to be the only solution to access properties of mixtures from within Modelica on both Windows and Linux systems. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola sofar. +This piece of software enables the user to access the Refprop fluid property database from within Modelica. Even though the code base is not very mature yet, this package seems to be the only solution to access properties of mixtures from within Modelica on both Windows and Linux systems. The aim is to develop wrapper classes and integrate them with the `Media` framework inside Modelica. It has only been tested with Dymola so far. ## Installation Instructions You can use the provided makefiles to compile and install the wrapper. The process should be straightforward. You can get the latest release from https://github.com/jowr/REFPROP2Modelica/releases @@ -25,7 +25,6 @@ For installing on a Linux machine, please follow these instructions 5. If you experience problems with older versions of this package, you can run `sudo make fixit` to create additonal aliases. This compiles and installs a dynamic library on your system. 6. ... and finally to remove the files from your system, please use `sudo make uninstall`. - ## General Remarks Please note that you need a working and licensed copy of Refprop in order to use the software provided here. This is not a replacement for Refprop, only a wrapper to use it with Modelica. @@ -36,3 +35,29 @@ If you are interested in this kind of software, you might also want to consider 1. https://github.com/Heineken/REFPROP2Modelica (The original version of this library) 2. https://github.com/thorade/HelmholtzMedia (A Modelica implementation the Helmholtz functions) 3. http://coolprop.sourceforge.net/ (A free fluid property library also based on Helmholtz formulation) + +# Usage notes on partial derivatives +There are four ways to compute partial derivatives determined by "partialDersInputChoice", an input the setState_phX() and setState_pTX() functions: + +1: none (default) + +2: partial derivatives of d wrt p,h,X +In two-phase region: numerical differentiation for all derivatives +In single phase region: dddX is numerical and others are analytical + +3: partial derivatives of d wrt p,h,X +In two-phase region: pseudo analytical (similar procedure as pure fluid - they give almost same result as method 2, and with less CPU effort). +In single phase region: dddX is numerical and others are analytical + +4: partial derivatives of d and h wrt p,T,X +In two-phase region: numerical differentiation for all derivatives +In single phase region: dddX is numerical and others are analytical + +The second and fourth methods compare exactly with stepping forward in u,d,X (the baseline with most CPU effort, due to tedious iteration in property functions at every time step, u,d,X -> T,p,h etc.). +Method 4 is guicker in the two-phase region compared to method 2, because T and P are equilibrium quantities, and thus the most typical flash function.. +Method 3 is fastest, but does not give correct dynamics and will cause mass convervation to fail. + +Note that the dddX derivative is the difference in dddX1|X2=const-dddX2|X1=const + +The partials works only for binary mixtures and have only been tested for NH3/water.. +See tester package.. \ No newline at end of file From 662b0cd1fabcb23f1e56382c0193a414e53fd006 Mon Sep 17 00:00:00 2001 From: jowr Date: Thu, 5 Dec 2013 16:56:41 +0100 Subject: [PATCH 52/57] ready to roll back --- Examples/package.mo | 7 +++ Examples/package.order | 0 Interfaces/PartialMixtureTwoPhaseMedium.mo | 54 +++++++++++++++++++ Testers/PropsMixtureTwo.mo | 2 +- .../BaseProperties.mo | 50 +++++++++++++++++ .../ThermodynamicState.mo | 18 +++++++ .../bubbleEnthalpy.mo | 6 +++ Testers/Water_MixtureTwoPhase_pT/density.mo | 6 +++ .../dynamicViscosity.mo | 6 +++ .../Water_MixtureTwoPhase_pT/package.bak-mo | 22 ++++++++ .../Water_MixtureTwoPhase_pT/package.order | 20 +++++++ .../saturationPressure.mo | 6 +++ .../saturationTemperature.mo | 7 +++ .../Water_MixtureTwoPhase_pT/setState_pTX.mo | 7 +++ .../Water_MixtureTwoPhase_pT/setState_psX.mo | 7 +++ .../specificEnthalpy_pTX.mo | 15 ++++++ .../specificEnthalpy_ps.mo | 12 +++++ .../specificEntropy.mo | 6 +++ .../specificEntropy_pTX.mo | 13 +++++ .../specificHeatCapacityCp.mo | 17 ++++++ .../specificHeatCapacityCv.mo | 17 ++++++ .../Water_MixtureTwoPhase_pT/temperature.mo | 6 +++ .../temperature_phX.mo | 12 +++++ .../thermalConductivity.mo | 6 +++ _wrapper/Makefile | 1 + _wrapper/cpptest/refprop_c.c | 14 +++-- _wrapper/cpptest/refprop_c.h | 2 + _wrapper/src/refprop_wrapper.cpp | 2 +- 28 files changed, 331 insertions(+), 10 deletions(-) create mode 100644 Examples/package.mo create mode 100644 Examples/package.order create mode 100644 Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/density.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/package.bak-mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/package.order create mode 100644 Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/setState_psX.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/temperature.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo create mode 100644 Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo diff --git a/Examples/package.mo b/Examples/package.mo new file mode 100644 index 0000000..c332612 --- /dev/null +++ b/Examples/package.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica; +package Examples "Demonstration of the usage of the library" + extends Modelica.Icons.ExamplesPackage; + + + annotation(preferedView = "info", __Dymola_classOrder = {"PumpingSystem","HeatingSystem","DrumBoiler","Tanks","ControlledTankSystem","AST_BatchPlant","IncompressibleFluidNetwork","BranchingDynamicPipes","HeatExchanger","TraceSubstances","InverseParameterization","Explanatory","*"}); +end Examples; diff --git a/Examples/package.order b/Examples/package.order new file mode 100644 index 0000000..e69de29 diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index f45cd16..8073cbd 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -522,6 +522,23 @@ Functions to obtain fluid properties from the currently active state. annotation(Documentation(info="")); end density_pTX; +replaceable function pressure_dTX "Return pressure from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output AbsolutePressure p "Pressure"; +algorithm + p := pressure( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end pressure_dTX; + replaceable function specificEnthalpy_dTX "Return specific enthalpy from d, T, and X or Xi" extends Modelica.Icons.Function; @@ -578,6 +595,24 @@ end specificEnthalpy_dTX; annotation(Documentation(info="")); end specificEnthalpy_pTX; +replaceable function specificEntropy_dTX + "Return specific entropy from d, T, and X or Xi" + extends Modelica.Icons.Function; + input Density d "Density"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_dTX( + d, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_dTX; + replaceable function specificEntropy_phX "Return specific entropy from p, h, and X or Xi" extends Modelica.Icons.Function; @@ -596,6 +631,24 @@ algorithm annotation(Documentation(info="")); end specificEntropy_phX; +replaceable function specificEntropy_pTX + "Return specific entropy from p, T, and X or Xi" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input Temperature T "Temperature"; + input MassFraction X[nX] "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEntropy s "specific enthalpy"; +algorithm + s := specificEntropy( + setState_pTX( + p, + T, + X, + phase)); +annotation(Documentation(info="")); +end specificEntropy_pTX; + redeclare replaceable function temperature_phX "Return temperature from p, h, and X or Xi" extends Modelica.Icons.Function; @@ -615,6 +668,7 @@ end specificEntropy_phX; annotation(Documentation(info="")); end temperature_phX; + redeclare replaceable function temperature_psX "Return temperature from p, s, and X or Xi" extends Modelica.Icons.Function; diff --git a/Testers/PropsMixtureTwo.mo b/Testers/PropsMixtureTwo.mo index c4b8698..77bdb33 100644 --- a/Testers/PropsMixtureTwo.mo +++ b/Testers/PropsMixtureTwo.mo @@ -22,6 +22,6 @@ Modelica.SIunits.Pressure p(min=10,max=10e6)=Medium.pressure(props.state); equation props.p = 1e5; props.h = 0+time*8e5; - props.Xi = {.5}; + props.Xi = {0.5}; end PropsMixtureTwo; diff --git a/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo b/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo new file mode 100644 index 0000000..2b1ef47 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/BaseProperties.mo @@ -0,0 +1,50 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +model extends BaseProperties "Base properties of medium" + Real GVF = q * d / d_g "gas void fraction"; + Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_T(T); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_T(T); + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.rhov_p(p);*/ + /* Modelica.SIunits.Density d_l = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_p(p); + Modelica.SIunits.Density d_g = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhov_p(p);*/ + Modelica.SIunits.SpecificEnthalpy h_l = bubbleEnthalpy(sat); + Modelica.SIunits.SpecificEnthalpy h_g = dewEnthalpy(sat); + Real q = min(max((h - h_l) / (h_g - h_l + 1e-18), 0), 1) + "(min=0,max=1) gas phase mass fraction"; + // Integer phase_out "calculated phase"; + //END no gas case +equation + u = h - p / d; + MM = M_H2O; + R = Modelica.Constants.R / MM; + //End GVF + //DENSITY + // q = vapourQuality(state); + d = Modelica.Media.Water.WaterIF97_base.density_ph(p, h); + // d = d_l/(1-q*(1-d_l/d_g)); + //End DENSITY + //ENTHALPY + h = specificEnthalpy_pTX(p, T, X); + /* + if (p_H2O>p) then + h_H2O_g = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p,T,1); + else + h_H2O_g = Modelica.Media.Water.WaterIF97_base.dewEnthalpy(Modelica.Media.Water.WaterIF97_base.setSat_p(p)); + end if; + h_gas_dissolved = 0; + Delta_h_solution = solutionEnthalpy(T) + "TODO: gilt nur bei ges�ttigter L�sung"; +*/ + //assert(abs(((1-q)*h_l + q*h_g-h)/h) < 1e-3,"Enthalpie stimmt nicht! h_calc="+String((1-q)*h_l + q*h_g)+"<>h="+String(h)); + //End ENTHALPY + s = 0 "TODO"; + state = ThermodynamicState(p= p, T= T, X= X, X_l= X, h= h, GVF= GVF, q= q, s= 0, d_g= d_g, d_l= d_l, d= d, phase= 0) + "phase_out"; + sat.psat = p "TODO"; + sat.Tsat = T "saturationTemperature(p) TODO"; + sat.X = X; + annotation(Documentation(info = ""), Documentation(revisions = " + +")); +end BaseProperties; + diff --git a/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo b/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo new file mode 100644 index 0000000..18e4c5e --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/ThermodynamicState.mo @@ -0,0 +1,18 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +record extends ThermodynamicState + "a selection of variables that uniquely defines the thermodynamic state" + /* AbsolutePressure p "Absolute pressure of medium"; + Temperature T(unit="K") "Temperature of medium"; + MassFraction X[nX] "Mass fraction of NaCl in kg/kg";*/ + SpecificEnthalpy h "Specific enthalpy"; + SpecificEntropy s "Specific entropy"; + Density d(start = 300) "density"; + Real GVF "Gas Void Fraction"; + Density d_l(start = 300) "density liquid phase"; + Density d_g(start = 300) "density gas phase"; + Real q "vapor quality on a mass basis [mass vapor/total mass]"; + annotation(Documentation(info = " + +")); +end ThermodynamicState; + diff --git a/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo b/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo new file mode 100644 index 0000000..c42d2b8 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/bubbleEnthalpy.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends bubbleEnthalpy "boiling curve specific enthalpy of water" +algorithm + hl:=Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat); +end bubbleEnthalpy; + diff --git a/Testers/Water_MixtureTwoPhase_pT/density.mo b/Testers/Water_MixtureTwoPhase_pT/density.mo new file mode 100644 index 0000000..7dee4e0 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/density.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends density "return density of ideal gas" +algorithm + d:=state.d; +end density; + diff --git a/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo b/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo new file mode 100644 index 0000000..5e67604 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/dynamicViscosity.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends dynamicViscosity +algorithm + eta:=Modelica.Media.Water.WaterIF97_base.dynamicViscosity(state); +end dynamicViscosity; + diff --git a/Testers/Water_MixtureTwoPhase_pT/package.bak-mo b/Testers/Water_MixtureTwoPhase_pT/package.bak-mo new file mode 100644 index 0000000..cd45770 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/package.bak-mo @@ -0,0 +1,22 @@ +within REFPROP2Modelica.Testers; +package Water_MixtureTwoPhase_pT "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" + extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium(final mediumName = "TwoPhaseMixtureWater", final substanceNames = {"water"}, final reducedX = true, final singleState = false, reference_X = cat(1, fill(0, nX - 1), {1}), fluidConstants = BrineConstants); + // final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, + constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; + + annotation(Documentation(info = " +

Water_MixtureTwoPhase_pT

+ This is a an example use of PartialMixtureTwoPhaseMedium. + It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
+ +

Created by

+Henning Francke
+Helmholtz Centre Potsdam
+GFZ German Research Centre for Geosciences
+Telegrafenberg, D-14473 Potsdam
+Germany +

+francke@gfz-potsdam.de + +")); +end Water_MixtureTwoPhase_pT; diff --git a/Testers/Water_MixtureTwoPhase_pT/package.order b/Testers/Water_MixtureTwoPhase_pT/package.order new file mode 100644 index 0000000..72b850c --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/package.order @@ -0,0 +1,20 @@ +M_H2O +BaseProperties +bubbleEnthalpy +density +dewEnthalpy +dynamicViscosity +saturationPressure +saturationTemperature +setState_psX +setState_pTX +specificEnthalpy_ps +specificEnthalpy_pTX +specificEntropy +specificEntropy_pTX +specificHeatCapacityCp +specificHeatCapacityCv +temperature +temperature_phX +thermalConductivity +ThermodynamicState diff --git a/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo b/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo new file mode 100644 index 0000000..6848b0f --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/saturationPressure.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends saturationPressure +algorithm + p:=Modelica.Media.Water.WaterIF97_base.saturationPressure(T); +end saturationPressure; + diff --git a/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo b/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo new file mode 100644 index 0000000..0be8c96 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/saturationTemperature.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends saturationTemperature +algorithm + //T := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p); + T:=Modelica.Media.Water.WaterIF97_base.saturationTemperature(p); +end saturationTemperature; + diff --git a/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo new file mode 100644 index 0000000..0c42d26 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/setState_pTX.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends setState_pTX + "Return thermodynamic state of water as function of p and T" +algorithm + state:=ThermodynamicState(d= density_pT(p, T), T= T, phase= 0, h= specificEnthalpy_pTX(p, s), p= p, X= X, s= specificEntropy_pT(p.T), q= -1, GVF= -1, d_l= -1, d_g= -1); +end setState_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo b/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo new file mode 100644 index 0000000..72c1ea4 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/setState_psX.mo @@ -0,0 +1,7 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends setState_psX + "Return thermodynamic state of water as function of p and s" +algorithm + state:=ThermodynamicState(d= density_ps(p, s), T= temperature_ps(p, s), phase= 0, h= specificEnthalpy_ps(p, s), p= p, X= X, s= s, q= -1, GVF= -1, d_l= -1, d_g= -1); +end setState_psX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo new file mode 100644 index 0000000..57e4e47 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_pTX.mo @@ -0,0 +1,15 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEnthalpy_pTX + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.Temp_K T; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + /* input MassFraction q "(min=0,max=1)"; + input Real y "molar fraction of gas in gas phase";*/ + // input Real[3] TP; + output Modelica.SIunits.SpecificEnthalpy h = Modelica.Media.Water.WaterIF97_base.specificEnthalpy_pT(p, T); +algorithm + // Modelica.Utilities.Streams.print("specificEnthalpy_pTXqy("+String(p)+","+String(T)+",X,"+String(q)+","+String(y)+")"); + annotation(LateInline = true, inverse(T = temperature_phX(p= p, h= h, X= X, phase= phase))); +end specificEnthalpy_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo new file mode 100644 index 0000000..79f8a21 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEnthalpy_ps.mo @@ -0,0 +1,12 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEnthalpy_ps + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy s "Specific entropy"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy h "specific enthalpy"; +algorithm + h:=Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEnthalpy_ps; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo b/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo new file mode 100644 index 0000000..46807ba --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEntropy.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificEntropy "specific entropy of water" +algorithm + s:=Modelica.Media.Water.IF97_Utilities.s_ph(state.p, state.h, state.phase); +end specificEntropy; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo b/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo new file mode 100644 index 0000000..97f54f6 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificEntropy_pTX.mo @@ -0,0 +1,13 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function specificEntropy_pTX + "Computes specific enthalpy as a function of pressure and temperature" + extends Modelica.Icons.Function; + input AbsolutePressure p "Pressure"; + input SpecificEntropy T "Specific entropy"; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output SpecificEnthalpy s "specific enthalpy"; +algorithm + h:=Modelica.Media.Water.IF97_Utilities.h_ps(p, s, phase); +end specificEntropy_pTX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo new file mode 100644 index 0000000..b9ed244 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCp.mo @@ -0,0 +1,17 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificHeatCapacityCp + "specific heat capacity at constant pressure of water" +algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cp:=Modelica.Media.Water.IF97_Utilities.cp_dT(state.d, state.T, state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cp:=Modelica.Media.Water.IF97_Utilities.cp_pT(state.p, state.T); + else + cp:=Modelica.Media.Water.IF97_Utilities.cp_ph(state.p, state.h, state.phase); + end if; + annotation(Documentation(info = " +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); +end specificHeatCapacityCp; + diff --git a/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo new file mode 100644 index 0000000..2bf961e --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/specificHeatCapacityCv.mo @@ -0,0 +1,17 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends specificHeatCapacityCv + "specific heat capacity at constant pressure of water" +algorithm + if Modelica.Media.Water.WaterIF97_base.dT_explicit then + cv:=Modelica.Media.Water.IF97_Utilities.cv_dT(state.d, state.T, state.phase); + elseif Modelica.Media.Water.WaterIF97_base.pT_explicit then + cv:=Modelica.Media.Water.IF97_Utilities.cv_pT(state.p, state.T); + else + cv:=Modelica.Media.Water.IF97_Utilities.cv_ph(state.p, state.h, state.phase); + end if; + annotation(Documentation(info = " +

In the two phase region this function returns the interpolated heat capacity between the + liquid and vapour state heat capacities.

+ ")); +end specificHeatCapacityCv; + diff --git a/Testers/Water_MixtureTwoPhase_pT/temperature.mo b/Testers/Water_MixtureTwoPhase_pT/temperature.mo new file mode 100644 index 0000000..365dcf7 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/temperature.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends temperature "return temperature of ideal gas" +algorithm + T:=state.T; +end temperature; + diff --git a/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo b/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo new file mode 100644 index 0000000..beef10d --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/temperature_phX.mo @@ -0,0 +1,12 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function temperature_phX "numerically inverts specificEnthalpy_liquid_pTX" + input Modelica.SIunits.Pressure p; + input Modelica.SIunits.SpecificEnthalpy h; + input MassFraction X[:] "mass fraction m_XCl/m_Sol"; + input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known"; + output Modelica.SIunits.Temp_K T = Modelica.Media.Water.WaterIF97_base.temperature_ph(p, h); +algorithm + // Modelica.Utilities.Streams.print("temperature_phX"); + annotation(LateInline = true, inverse(h = specificEnthalpy_pTX(p= p, T= T, phase= phase, X= X))); +end temperature_phX; + diff --git a/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo b/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo new file mode 100644 index 0000000..3264a22 --- /dev/null +++ b/Testers/Water_MixtureTwoPhase_pT/thermalConductivity.mo @@ -0,0 +1,6 @@ +within REFPROP2Modelica.Testers.Water_MixtureTwoPhase_pT; +function extends thermalConductivity "Thermal conductivity of water" +algorithm + lambda:=Modelica.Media.Water.IF97_Utilities.thermalConductivity(state.d, state.T, state.p, state.phase); +end thermalConductivity; + diff --git a/_wrapper/Makefile b/_wrapper/Makefile index 4b6ba10..231b757 100644 --- a/_wrapper/Makefile +++ b/_wrapper/Makefile @@ -76,6 +76,7 @@ install_dynamic : header library $(CP) $(BINDIR)/$(LIBHEADER)$(HEADEREXTENSION) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) $(CP) $(BINDIR)/$(LIBRARY)$(LIBRARYEXTENSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) $(CH) $(HEADINST)/$(HEADERFILE)$(HEADEREXTENSION) + $(CH) $(HEADINST)/$(LIBHEADER)$(HEADEREXTENSION) $(CH) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) $(LD) -l $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION).$(MINORVERSION) $(LN) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION).$(MAJORVERSION) $(LIBINST)/$(LIBRARY)$(LIBRARYEXTENSION) diff --git a/_wrapper/cpptest/refprop_c.c b/_wrapper/cpptest/refprop_c.c index e4f9ed8..8bd009c 100644 --- a/_wrapper/cpptest/refprop_c.c +++ b/_wrapper/cpptest/refprop_c.c @@ -78,17 +78,15 @@ int main(int argc, char* argv[]) #if defined(__ISWINDOWS__) - HINSTANCE RefpropdllInstance; RefpropdllInstance = LoadLibrary("C:\\Program Files (x86)\\REFPROP\\refprop.dll"); PHFLSHdll = (fp_PHFLSHdllTYPE) GetProcAddress(RefpropdllInstance,"PHFLSHdll"); - SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(RefpropdllInstance,"SETUPdll"); - XMOLEdll = (fp_XMOLEdllTYPE) GetProcAddress(RefpropdllInstance,"XMOLEdll"); + SETUPdll = (fp_SETUPdllTYPE) GetProcAddress(RefpropdllInstance,"SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) GetProcAddress(RefpropdllInstance,"XMOLEdll"); #elif defined(__ISLINUX__) - void *RefpropdllInstance = NULL; RefpropdllInstance = dlopen("librefprop.so", RTLD_LAZY); - PHFLSHdll = (fp_PHFLSHdllTYPE) dlsym(RefpropdllInstance, "PHFLSHdll"); - SETUPdll = (fp_SETUPdllTYPE) dlsym(RefpropdllInstance, "SETUPdll"); - XMOLEdll = (fp_XMOLEdllTYPE) dlsym(RefpropdllInstance, "XMOLEdll"); + PHFLSHdll = (fp_PHFLSHdllTYPE) dlsym(RefpropdllInstance, "PHFLSHdll"); + SETUPdll = (fp_SETUPdllTYPE) dlsym(RefpropdllInstance, "SETUPdll"); + XMOLEdll = (fp_XMOLEdllTYPE) dlsym(RefpropdllInstance, "XMOLEdll"); #endif @@ -111,7 +109,7 @@ int main(int argc, char* argv[]) FLD_PATH = "C:\\Program Files (x86)\\REFPROP\\fluids"; char theSepChar[2] = "\\"; # elif defined(__ISLINUX__) - FLD_PATH = "/opt/refprop"; + FLD_PATH = "/opt/refprop/fluids"; char theSepChar[2] = "/"; # endif // strcpy(hf,FLD_PATH); diff --git a/_wrapper/cpptest/refprop_c.h b/_wrapper/cpptest/refprop_c.h index 9abea59..ec0f266 100644 --- a/_wrapper/cpptest/refprop_c.h +++ b/_wrapper/cpptest/refprop_c.h @@ -16,11 +16,13 @@ #endif #if defined(__ISWINDOWS__) +HINSTANCE RefpropdllInstance; // For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" typedef void (__stdcall *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); typedef void (__stdcall *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); typedef void (__stdcall *fp_XMOLEdllTYPE)(double *,double *,double *); #elif defined(__ISLINUX__) +void *RefpropdllInstance; // For C calling conventions, replaced all "double &" with "double *", and "long &" with "long *" typedef void ( *fp_PHFLSHdllTYPE)(double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,double *,long *,char*,long ); typedef void ( *fp_SETUPdllTYPE)(long *,char*,char*,char*,long *,char*,long ,long ,long ,long ); diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 03e838a..11e45a2 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -612,7 +612,7 @@ double loadLibrary(std::string sPath) { #else sPath.append((LPCSTR)pathSep); sPath.append((LPCSTR)libName); - RefpropdllInstance = LoadLibrary(sPath.c_str()); // this works in cpp tester, but not in Modelica.. + RefpropdllInstance = LoadLibrary(sPath.c_str()); #endif #elif defined(__ISLINUX__) RefpropdllInstance = dlopen(libName, RTLD_LAZY); From 422e1024f8a80c64832076022624738402385a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Tue, 11 Feb 2014 10:04:30 +0100 Subject: [PATCH 53/57] updated wrapper with criticalproperties function.. --- _wrapper/cpptest/cpp_wrapped.cpp | 30 ++++++++++++++++++++++ _wrapper/src/refprop_wrapper.cpp | 44 ++++++++++++++++++++++++++++++++ _wrapper/src/refprop_wrapper.h | 1 + 3 files changed, 75 insertions(+) diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index dd12e54..cd1f69c 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -20,6 +20,8 @@ int main(int argc, char* argv[]){ int partialDersInputChoice= 3; double *satprops; + double *critprops; + double *transprops; int nX=2; // Number of components @@ -41,6 +43,9 @@ int main(int argc, char* argv[]){ satprops = (double*) calloc(12+nX,sizeof(double)); + critprops = (double*) calloc(3+nX,sizeof(double)); + transprops = (double*) calloc(2,sizeof(double)); + char fluidname[255] = "ammoniaL|water"; x[0] = 0.5; x[1] = 1.0 - x[0]; @@ -185,5 +190,30 @@ int main(int argc, char* argv[]){ out << buffer << std::endl << std::endl << std::endl; printf("%s",out.str().c_str()); + + + x[0]=0; + x[1]=1; + + res = critprops_REFPROP(fluidname, critprops, x, thepathChar, errormsg, DEBUG); + + printf("%f\n",critprops[0]); + printf("%f\n",critprops[1]); + printf("%f\n",critprops[2]); + printf("%f\n",critprops[3]); + printf("%f\n",critprops[4]); + + res = critprops_REFPROP(fluidname, critprops, x, thepathChar, errormsg, DEBUG); + + printf("%f\n",critprops[0]); + printf("%f\n",critprops[1]); + printf("%f\n",critprops[2]); + printf("%f\n",critprops[3]); + printf("%f\n",critprops[4]); + + x[0]=1; + x[1]=0; + return 0; + } diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 11e45a2..ac3d0aa 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -103,6 +103,9 @@ int PartialDersInputChoice; //long lerr; // Error return mechanism double dhelp = noValue; + + + // Properties for setSat functions double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat, dxmollsat[ncmax],dxmolvsat[ncmax],dplsat,dhlsat,dslsat, @@ -2749,3 +2752,44 @@ OUTPUT return -1.0; } } + + + + +double critprops_REFPROP(char* fluidnames, double *critprops, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE){ +/*Calculates crit */ + + double dxmolcrit[ncmax]; + double dwmcrit; + long lerr = 0; + if (DEBUGMODE) debug = true; + std::string fluids = std::string(fluidnames); + std::string rPath = std::string(REFPROP_PATH); + /* + * Call method to initialise the library and check for new fluids. + */ + if (setFluids(rPath,fluids,errormsg) != OK) { + printf("Error initialising REFPROP: \"%s\"\n", errormsg); + return -FAIL; + } + // Convert mass-based composition to mole fractions and set molecular weight. + dxkg = x; + XMOLEdll(dxkg,dxmolcrit,dwmcrit); + + CRITPdll(dxmolcrit,critprops[0],critprops[1],critprops[2],lerr,errormsg,errormessagelength); + + critprops[1]=critprops[1]*1000; //convert from kPa to Pa + critprops[2]=critprops[2]*dwmcrit; //convert from mol/L to g/L = kg/m3 + + if (lerr==1) { + strcpy(errormsg,"CRITP did not converge"); + } + + for (int ii=0;ii Date: Mon, 16 Jun 2014 13:58:13 +0200 Subject: [PATCH 54/57] Use SATSPLN whenever an error occurs, or output liquid density is lower than that of gas.. included a saturation state to the setState calls, so all props are essentially output.. --- Interfaces/PartialMixtureTwoPhaseMedium.mo | 17 +- Interfaces/REFPROPMixtureTwoPhaseMedium.mo | 289 +++++++---- _wrapper/cpptest/cpp_wrapped.cpp | 33 +- _wrapper/src/refprop_library.h | 22 +- _wrapper/src/refprop_wrapper.cpp | 527 +++++++++++++++++---- _wrapper/src/refprop_wrapper.h | 2 +- 6 files changed, 669 insertions(+), 221 deletions(-) diff --git a/Interfaces/PartialMixtureTwoPhaseMedium.mo b/Interfaces/PartialMixtureTwoPhaseMedium.mo index 8073cbd..fa177b5 100644 --- a/Interfaces/PartialMixtureTwoPhaseMedium.mo +++ b/Interfaces/PartialMixtureTwoPhaseMedium.mo @@ -59,6 +59,7 @@ redeclare replaceable record extends ThermodynamicState MolarMass molarMass "Molar mass of bulk mixture"; FixedPhase phase(min=0, max=2) "phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g. interactive use"; + //PrandtlNumber Pr "prandtl number"; //Temperature T "temperature"; VelocityOfSound w(min=1e-8) "velocity of sound"; @@ -82,10 +83,9 @@ end ThermodynamicState; "Saturation properties of two phase medium" extends Modelica.Icons.Record; - Temperature Tl(min=1e-8) "saturation temperature at bubble line"; - Temperature Tv(min=1e-8) "saturation temperature at dew line"; - AbsolutePressure pl(min=1e-8) "saturation pressure at bubble line"; - AbsolutePressure pv(min=1e-8) "saturation pressure at dew line"; + Temperature Tsat; + AbsolutePressure psat; + MassFraction X[nX] "Mass fraction of bulk"; // Real dTp "derivative of Ts wrt pressure"; // DerDensityByPressure ddldp "derivative of dls wrt pressure"; // DerDensityByPressure ddvdp "derivative of dvs wrt pressure"; @@ -98,13 +98,11 @@ end ThermodynamicState; SpecificEntropy sl "specific entropy at bubble line (for pressure ps)"; SpecificEntropy sv "specific entropy at dew line (for pressure ps)"; SurfaceTension sigma "surface tension"; - MassFraction X[nX] "Bulk mass fractions"; + // MassFraction X[nX] "Bulk mass fractions"; // MolarMass MMl "molar mass bubble line (for pressure ps)"; // MolarMass MMv "molar mass at dew line (for pressure ps)"; - // MassFraction Xl[nX] "Mass fractions of liquid phase"; - // MassFraction Xv[nX] "Mass fractions of gaseous phase"; - AbsolutePressure psat annotation(HideResult=true); - Temperature Tsat annotation(HideResult=true); + MassFraction Xl[nX] "Mass fractions of liquid phase"; + MassFraction Xv[nX] "Mass fractions of gaseous phase"; end SaturationProperties; redeclare replaceable model extends BaseProperties( @@ -668,7 +666,6 @@ end specificEntropy_pTX; annotation(Documentation(info="")); end temperature_phX; - redeclare replaceable function temperature_psX "Return temperature from p, s, and X or Xi" extends Modelica.Icons.Function; diff --git a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo index 1e51374..d1ece26 100644 --- a/Interfaces/REFPROPMixtureTwoPhaseMedium.mo +++ b/Interfaces/REFPROPMixtureTwoPhaseMedium.mo @@ -54,9 +54,9 @@ partial package REFPROPMixtureTwoPhaseMedium //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() extends Modelica.Icons.Function; protected - Real[18 + 2*nX] props; + Real[21+ 2*nX] props; Real[12] ders; - Real[3] trns; + Real[4] trns; String errormsg=StrJoin(fill("xxxx", 64), "") "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; end partialREFPROP; @@ -134,7 +134,7 @@ partial package REFPROPMixtureTwoPhaseMedium //used by getSatProp_REFPROP_check() and getProp_REFPROP_check() extends Modelica.Icons.Function; protected - Real[12 + 1*nX] satprops; + Real[11 + 2*nX] satprops; String errormsg=StrJoin(fill("xxxx", 64), "") "Allocating memory, string will be written by C function, doesn't work for strings longer than 40 bytes"; // initial algorithm @@ -151,8 +151,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String fluidnames; input Real[:] satprops; input Real statevarval; - input Real Tsurft=0 - "additional temperature for surface tension function, in case of setSat_pX"; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; input Boolean calcTransport=false; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; input String errormsg; @@ -164,8 +164,8 @@ partial package REFPROPMixtureTwoPhaseMedium fluidnames, satprops, statevarval, - Tsurft, X, + kph, REFPROP_PATH, errormsg, debugmode, @@ -180,8 +180,8 @@ partial package REFPROPMixtureTwoPhaseMedium input String statevar; // input String fluidnames; input Real statevarval; - input Real Tsurft=0 - "additional temperature for surface tension function, in case of setSat_pX"; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; output Real val; algorithm @@ -192,8 +192,8 @@ partial package REFPROPMixtureTwoPhaseMedium fluidnames, satprops, statevarval, - Tsurft, X, + kph, errormsg) "just passing through"; //Error string decoding in wrapper-c-function assert(satprops[1] == 0 or satprops[1] == 141, "Errorcode " + String(satprops[1]) + " in REFPROP wrapper function:\n" @@ -211,15 +211,17 @@ end SaturationProperties; redeclare record extends ThermodynamicState "Adapt this record to the returned values from one REFPROP call." - Density d_l "density of liquid phase"; - Density d_g "density of gaseous phase"; + SaturationProperties sat "saturation properties"; + +// Density d_l "density of liquid phase"; +// Density d_g "density of gaseous phase"; // MassFraction x "void fraction"; // SpecificInternalEnergy u "Specific energy"; // MolarMass MM_l "Molar Mass of liquid phase"; // MolarMass MM_g "Molar Mass of gas phase"; - MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; - MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; +// MassFraction X_l[nX] "Composition of liquid phase (Mass fractions in kg/kg)"; +// MassFraction X_g[nX] "Composition of gas phase (Mass fractions in kg/kg)"; // DerDensityByEnthalpy ddhp // "derivative of density wrt enthalpy at constant pressure"; // DerDensityByPressure ddph @@ -391,20 +393,31 @@ end ThermodynamicState; If q = 999 Then Quality = Trim2("Supercritical state (T>Tc, p>pc)") If q = -998 Then Quality = Trim2("Subcooled liquid with p>pc")*/ state := ThermodynamicState( + sat=SaturationProperties( + Tsat=props[21], + psat=props[2], + X=X, + dl=props[6], + dv=props[7], + hl=props[17], + hv=props[18], + sl=props[19], + sv=props[20], + sigma=trns[4], + Xl={props[21+i] for i in 1:nX}, + Xv={props[21+nX+i] for i in 1:nX}), p=props[2], T=props[3], X=X, molarMass=props[4], d=props[5], - d_l=props[6], - d_g=props[7], h=props[10], s=props[11], cv=props[12], cp=props[13], w=props[14], phase=if (props[8] > 0 and props[8] < 1) then 2 else 1, - q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], + q= props[8], kappa=ders[2], beta=ders[3], dddX_ph=ders[4], @@ -417,9 +430,9 @@ end ThermodynamicState; dhdT_pX=ders[11], dhdX_pT=ders[12], eta=trns[2], - lambda=trns[3], - X_l={props[16+i] for i in 1:nX}, - X_g={props[16+nX+i] for i in 1:nX}); + lambda=trns[3]); + //q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], + // q=if (props[8] < 0) then 0 elseif (props[8] > 1) then 1 else props[8], if debugmode then Modelica.Utilities.Streams.print("Running state set to p,T,d,h,s (" @@ -451,6 +464,8 @@ end ThermodynamicState; redeclare replaceable function extends setState_dTX // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; algorithm if debugmode then Modelica.Utilities.Streams.print("Running setState_dTX(" + String(d) + "," @@ -461,7 +476,9 @@ end ThermodynamicState; d, T, X, - phase) ",fluidnames)"; + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; end setState_dTX; function setState_hsX "Calculates medium properties from h,s,X" @@ -551,52 +568,42 @@ end ThermodynamicState; redeclare function extends setBubbleState "set the thermodynamic state on the bubble line" algorithm - // if debugmode then - // Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - // + String(bubbleEnthalpy(sat)) + ",X)..."); - // end if; - // state := setState( - // "pq", - // sat.psat, - // 0, - // sat.X, - // phase) ",fluidnames)"; - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," - + String(sat.Tv) + ",X)..."); - end if; - state := setState( - "dT", - sat.dl, - sat.Tl, - sat.X, - phase); + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dl) + "," + // + String(sat.Tsat) + ",X)..."); + // end if; + // state := setState_dTX( + // sat.dl, + // sat.Tsat, + // sat.Xl, + // phase); + + state := setState_pqX( + sat.psat, + 0, + sat.X); end setBubbleState; redeclare function extends setDewState "set the thermodynamic state on the bubble line" - algorithm - // if debugmode then - // Modelica.Utilities.Streams.print("Running setState_phX(" + String(sat.psat) + "," - // + String(dewEnthalpy(sat)) + ",X)..."); - // end if; - // state := setState( - // "pq", - // sat.psat, - // 1, - // sat.X, - // phase) ",fluidnames)"; - if debugmode then - Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," - + String(sat.Tv) + ",X)..."); - end if; - state := setState( - "dT", - sat.dv, - sat.Tv, - sat.X, - phase); + //input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + //input Boolean calcTransport=false; + algorithm + // if debugmode then + // Modelica.Utilities.Streams.print("Running setState_dTX(" + String(sat.dv) + "," + // + String(sat.Tsat) + ",X)..."); + // end if; + // state := setState_dTX( + // sat.dv, + // sat.Tsat, + // sat.Xv, + // phase); + + state := setState_pqX( + sat.psat, + 1, + sat.X); end setDewState; @@ -607,6 +614,8 @@ end ThermodynamicState; input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; output ThermodynamicState state "thermodynamic state record"; algorithm if debugmode then @@ -618,9 +627,36 @@ end ThermodynamicState; p, q, X, - phase) ",fluidnames)"; + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; end setState_pqX; + function setState_TqX "Calculates medium properties from p,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.Temperature T "Temperature"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_tqX(" + String(T) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "tq", + T, + q, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_TqX; + redeclare replaceable partial function extends setState_psX "Calculates medium properties from p,s,X" // input String fluidnames; @@ -703,8 +739,8 @@ end ThermodynamicState; input String statevar; input Real statevarval; input Modelica.SIunits.MassFraction X[:] "Mass fractions"; - input Real Tsurft=0 - "additional temperature for surface tension function, in case of setSat_pX"; + input Integer kph(min=1,max=2) + "phase specification, 1=>X is liquid, 2=>X is vapor"; input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm @@ -715,27 +751,25 @@ end ThermodynamicState; fluidnames, satprops, statevarval, - Tsurft, + kph, calcTransport, X, errormsg); assert(satprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); sat := SaturationProperties( - psat=99999, - Tsat=99999, - Tl=satprops[2], - Tv=satprops[3], - pl=satprops[4], - pv=satprops[5], - dl=satprops[6], - dv=satprops[7], - hl=satprops[8], - hv=satprops[9], - sl=satprops[10], - sv=satprops[11], - sigma=satprops[12], - X= satprops[13:13+nX-1]); + Tsat=satprops[2], + psat=satprops[3], + X=X, + dl=satprops[4], + dv=satprops[5], + hl=satprops[6], + hv=satprops[7], + sl=satprops[8], + sv=satprops[9], + sigma=satprops[10], + Xl= satprops[11:11+nX-1], + Xv= satprops[11+nX:11+2*nX-1]); end setSat; redeclare replaceable function setSat_pX @@ -743,8 +777,8 @@ end ThermodynamicState; extends Modelica.Icons.Function; input AbsolutePressure p "pressure"; input MassFraction X[nX] "Mass fractions"; - input Real Tsurft=0 - "additional temperature for surface tension function, in case of setSat_pX"; + input Integer kph(min=1,max=2)=1 + "phase specification, 1=>X is liquid, 2=>X is vapor"; input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm @@ -752,7 +786,7 @@ end ThermodynamicState; "p", p, X, - Tsurft, + kph, calcTransport); end setSat_pX; @@ -761,6 +795,8 @@ end ThermodynamicState; extends Modelica.Icons.Function; input Temperature T "temperature"; input MassFraction X[nX] "Mass fractions"; + input Integer kph(min=1,max=2)=1 + "phase specification, 1=>X is liquid, 2=>X is vapor"; input Boolean calcTransport=false; output SaturationProperties sat "saturation property record"; algorithm @@ -768,21 +804,10 @@ end ThermodynamicState; "t", T, X, + kph, calcTransport=calcTransport); end setSat_TX; - redeclare function extends saturationPressure - algorithm - // this function does not make sense, what pressure do you want? - // use setSat instead - end saturationPressure; - - redeclare function extends saturationTemperature - algorithm - // this function does not make sense, what temperature do you want? - // use setSat instead - end saturationTemperature; - // redeclare function extends specificEntropy // "Return specific entropy - seems useless, but good for compatibility between PartialMedium and PartialMixedMediumTwoPhase" // algorithm @@ -1943,7 +1968,7 @@ end ThermodynamicState; cv := state.cv; end specificHeatCapacityCv; - redeclare function extends thermalConductivity + redeclare replaceable function extends thermalConductivity algorithm if debugmode then Modelica.Utilities.Streams.print("Running thermalConductivity"); @@ -1951,7 +1976,7 @@ end ThermodynamicState; lambda := state.lambda; end thermalConductivity; - redeclare function extends dynamicViscosity + redeclare replaceable function extends dynamicViscosity algorithm if debugmode then Modelica.Utilities.Streams.print("Running dynamicViscosity"); @@ -2002,6 +2027,78 @@ end ThermodynamicState; X, calcTransport=calcTransport); end setSat_T; + + partial function partialCritREFPROP "Declaration of array props" + extends Modelica.Icons.Function; + protected + Real[1] critprops; + String errormsg=StrJoin(fill("xxxx", 64), ""); + + end partialCritREFPROP; + + function getCritProp_REFPROP + input String fluidnames; + input Real[:] critprops; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + external"C" val= critprops_REFPROP( + fluidnames, + critprops, + X, + REFPROP_PATH, + errormsg, + debugmode); + annotation (Include="#include ", Library="refprop_wrapper"); + end getCritProp_REFPROP; + + function setCrit + extends partialCritREFPROP; + input Modelica.SIunits.MassFraction X[:] "Mass fractions"; + output Real Tc(unit="K") "critical temperature K"; + // output Real pc(unit="kPa") "critical pressure, kPa"; + // output Real dc(unit="mol/l") "critical molar density, mol/L"; + // output MoleFraction[nX] Z "mole fraction"; + + algorithm + getCritProp_REFPROP( + fluidnames, + critprops, + X, + errormsg); + assert(critprops[1] == 0, "Error in REFPROP wrapper function: " + errormsg + "\n"); + + Tc:=critprops[1]; + // pc:=critprops[2]; + // dc:=critprops[3]; + // Z:=critprops[4:4+nX-1]; + + end setCrit; + + function setState_dqX "Calculates medium properties from d,q,X" + extends Modelica.Icons.Function; + input Modelica.SIunits.Density d "Pressure"; + input Modelica.SIunits.MassFraction q "quality (vapor mass fraction)"; + input Modelica.SIunits.MassFraction X[:]=reference_X "Mass fractions"; + input FixedPhase phase=0 "2 for two-phase, 1 for one-phase, 0 if not known"; + // input String fluidnames; + input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + input Boolean calcTransport=false; + output ThermodynamicState state "thermodynamic state record"; + algorithm + if debugmode then + Modelica.Utilities.Streams.print("Running setState_dqX(" + String(d) + "," + + String(q) + ",X)..."); + end if; + state := setState( + "dq", + d, + q, + X, + phase, + partialDersInputChoice, + calcTransport) ",fluidnames)"; + end setState_dqX; annotation (Documentation(info="

REFPROPMedium is a package that delivers REFPROP data to a model based on and largely compatible to the Modelica.Media library. diff --git a/_wrapper/cpptest/cpp_wrapped.cpp b/_wrapper/cpptest/cpp_wrapped.cpp index cd1f69c..d11c8ca 100644 --- a/_wrapper/cpptest/cpp_wrapped.cpp +++ b/_wrapper/cpptest/cpp_wrapped.cpp @@ -19,6 +19,8 @@ int main(int argc, char* argv[]){ int transport = 0; int partialDersInputChoice= 3; + int kph=1; // concentration is liquid + double *satprops; double *critprops; double *transprops; @@ -37,11 +39,11 @@ int main(int argc, char* argv[]){ // Allocate space for objects x = (double*) calloc(nX,sizeof(double)); - props = (double*) calloc(18+2*nX,sizeof(double)); + props = (double*) calloc(20+2*nX,sizeof(double)); ders = (double*) calloc(12,sizeof(double)); - trns = (double*) calloc(3,sizeof(double)); + trns = (double*) calloc(4,sizeof(double)); - satprops = (double*) calloc(12+nX,sizeof(double)); + satprops = (double*) calloc(10+2*nX,sizeof(double)); critprops = (double*) calloc(3+nX,sizeof(double)); transprops = (double*) calloc(2,sizeof(double)); @@ -82,23 +84,30 @@ int main(int argc, char* argv[]){ sprintf (buffer, "T = %8.4f [K]",props[2]); out << buffer << std::endl; - res = satprops_REFPROP((char*)"p", (char*)"t", fluidname, satprops, props[2], 0, x, thepathChar, errormsg, DEBUG, transport); - - sprintf (buffer, "Pl(T) = %8.4f [Pa]",satprops[3]); + kph=1; + x[0] = props[16]; + x[1] = props[17]; + res = satprops_REFPROP((char*)"p", (char*)"t", fluidname, satprops, props[2], x, kph, thepathChar, errormsg, DEBUG, transport); + sprintf (buffer, "P(T) = %8.4f [Pa]",satprops[2]); out << buffer << std::endl; - sprintf (buffer, "Pv(T) = %8.4f [Pa]",satprops[4]); + res = satprops_REFPROP((char*)"t", (char*)"p", fluidname, satprops, satprops[2], x, kph, thepathChar, errormsg, DEBUG, transport); + sprintf (buffer, "P(T) = %8.4f [Pa]",satprops[2]); out << buffer << std::endl; - res = satprops_REFPROP((char*)"t", (char*)"p", fluidname, satprops, p, 0, x, thepathChar, errormsg, DEBUG, transport); - sprintf (buffer, "Tl(p) = %8.4f [K]",satprops[1]); + kph=2; + x[0] = props[18]; + x[1] = props[19]; + res = satprops_REFPROP((char*)"p", (char*)"t", fluidname, satprops, props[2], x, kph, thepathChar, errormsg, DEBUG, transport); + sprintf (buffer, "T(p) = %8.4f [Pa]",satprops[1]); out << buffer << std::endl; - sprintf (buffer, "Tv(p) = %8.4f [K]",satprops[2]); + res = satprops_REFPROP((char*)"t", (char*)"p", fluidname, satprops, satprops[2], x, kph, thepathChar, errormsg, DEBUG, transport); + sprintf (buffer, "T(p) = %8.4f [Pa]",satprops[1]); out << buffer << std::endl; + x[0] = 0.5; + x[1] = 1.0 - x[0]; - sprintf (buffer, "Ders = %8.0f , %8.12f , %8.1f , %8.1f , %8.12f , %8.8f , %8.1f , %8.2f , %8.2f , %8.9f , %8.9f , %8.9f, %8.1f",ders[0],ders[1],ders[2],ders[3],ders[4],ders[5],ders[6],ders[7],ders[8],ders[18],ders[19],ders[20],ders[6]); - out << buffer << std::endl << std::endl; } } } diff --git a/_wrapper/src/refprop_library.h b/_wrapper/src/refprop_library.h index 61cc828..44c86ad 100644 --- a/_wrapper/src/refprop_library.h +++ b/_wrapper/src/refprop_library.h @@ -30,6 +30,7 @@ // names are needed. Macros still need a value for the // name function used below. # define RPVersion RPVersion +# define SATSPLNdll SATSPLNdll # define SETPATHdll SETPATHdll # define ABFL1dll ABFL1dll # define ABFL2dll ABFL2dll @@ -135,6 +136,8 @@ # define RDXHMXdll RDXHMXdll # define PHIXdll PHIXdll # define PHI0dll PHI0dll +# define DQFL2dll DQFL2dll + #elif defined(__ISLINUX__) // defined(__ISWINDOWS__) // Define compiler specific calling conventions @@ -150,6 +153,7 @@ // # if defined( _CRAY // However, I cannot test that and therefore do not include it. # define RPVersion rpversion_ +# define SATSPLNdll satsplndll_ # define SETPATHdll setpathdll_ # define ABFL1dll abfl1dll_ # define ABFL2dll abfl2dll_ @@ -255,11 +259,13 @@ # define RDXHMXdll rdxhmxdll_ # define PHIXdll phixdll_ # define PHI0dll phi0dll_ +# define DQFL2dll dqfl2dll_ #else // #elif defined(__ISLINUX__) // Set some dummy names for the compiler # define CALLCONV # define RPVersion NOTAVAILABLE +# define SATSPLNdll satsplndll # define SETPATHdll setpathdll # define ABFL1dll abfl1dll # define ABFL2dll abfl2dll @@ -365,6 +371,7 @@ # define RDXHMXdll rdxhmxdll # define PHIXdll phixdll # define PHI0dll phi0dll +# define DQFL2dll dqfl2dll #endif // else branch // @@ -383,6 +390,7 @@ // handle the library later on. #define RPVersion_NAME FUNCTION_NAME(RPVersion) #define SETPATHdll_NAME FUNCTION_NAME(SETPATHdll) +#define SATSPLNdll_NAME FUNCTION_NAME(SATSPLNdll) #define ABFL1dll_NAME FUNCTION_NAME(ABFL1dll) #define ABFL2dll_NAME FUNCTION_NAME(ABFL2dll) #define ACTVYdll_NAME FUNCTION_NAME(ACTVYdll) @@ -487,6 +495,7 @@ #define RDXHMXdll_NAME FUNCTION_NAME(RDXHMXdll) #define PHIXdll_NAME FUNCTION_NAME(PHIXdll) #define PHI0dll_NAME FUNCTION_NAME(PHI0dll) +#define DQFL2dll_NAME FUNCTION_NAME(DQFL2dll) // // I'll try to follow this example from: @@ -499,6 +508,8 @@ extern "C" { #endif typedef void (CALLCONV RPVersion_TYPE)( char* ); typedef void (CALLCONV SETPATHdll_TYPE)( const char* ); + typedef void (CALLCONV SATSPLNdll_TYPE)(double *,long &,char*,long ); + // typedef void (CALLCONV ABFL1dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long ); typedef void (CALLCONV ABFL2dll_TYPE)(double &,double &,double *,long &,long &,double &,double &,double &,double &,double &,double &,double &,double *,double *,double &,double &,double &,double &,double *,double *,double &,long &,char*,long ); @@ -604,8 +615,7 @@ extern "C" { typedef void (CALLCONV RDXHMXdll_TYPE)(long *,long *,long *,double *,double &,double &,long &,char*,long ); typedef void (CALLCONV PHIXdll_TYPE)(long *,long *,double &,double &,double *,double &); typedef void (CALLCONV PHI0dll_TYPE)(long *,long *,double &,double &,double *,double &); - - + typedef void (CALLCONV DQFL2dll_TYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double *,double *,long &,char*,long ); // // Disabled because we prefer pointers here! @@ -712,8 +722,14 @@ extern "C" { // XMOLEdll_TYPE XMOLEdll; // // Define explicit function pointers + + + + + typedef RPVersion_TYPE * RPVersion_POINTER; typedef SETPATHdll_TYPE * SETPATHdll_POINTER; + typedef SATSPLNdll_TYPE * SATSPLNdll_POINTER; typedef ABFL1dll_TYPE * ABFL1dll_POINTER; typedef ABFL2dll_TYPE * ABFL2dll_POINTER; typedef ACTVYdll_TYPE * ACTVYdll_POINTER; @@ -818,6 +834,8 @@ extern "C" { typedef RDXHMXdll_TYPE * RDXHMXdll_POINTER; typedef PHIXdll_TYPE * PHIXdll_POINTER; typedef PHI0dll_TYPE * PHI0dll_POINTER; + typedef DQFL2dll_TYPE * DQFL2dll_POINTER; + diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index ac3d0aa..381622c 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -108,9 +108,8 @@ double dhelp = noValue; // Properties for setSat functions double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat, - dxmollsat[ncmax],dxmolvsat[ncmax],dplsat,dhlsat,dslsat, - dcvlsat,dcplsat,dwlsat,dpvsat,dhvsat,dsvsat,dcvvsat,dcpvsat, - dwvsat,dtlsat,dtvsat; + dxmollsat[ncmax],dxmolvsat[ncmax],dhlsat,dslsat, + dwlsat,dhvsat,dsvsat,dwvsat,ddsat; /* * Most of the fluid properties are stored here. There are arrays for @@ -121,9 +120,13 @@ double dxmolsat[ncmax], dwmsat, dpsat, dtsat,ddlsat,ddvsat, */ double dt, dp, de, dh, ds, dqmol, dd, dxmol[ncmax], ddl, ddv, dxmoll[ncmax], dxmolv[ncmax], dCv, dCp, dw, dwliq, dwvap, - dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta; + dhjt, dZ[ncmax], dA, dG, dxkappa, dbeta, + dhl,dhv,dsl,dsv,dsigma,dts; double *dxkg; +double dxkg_old[ncmax]; +double dx1kg_old; +double dx1molsat_old; // viscosity and thermal conductivity double deta, dtcx; @@ -144,6 +147,11 @@ int flushProperties(){ dxmol[0]=noValue; ddl=noValue; ddv=noValue; + dhl=noValue; + dhv=noValue; + dsl=noValue; + dsv=noValue; + dxmoll[0]=noValue; dxmolv[0]=noValue; dCv=noValue; @@ -160,6 +168,7 @@ int flushProperties(){ dbeta=noValue; deta=noValue; dtcx=noValue; + dsigma=noValue; ddddX_ph=noValue; ddddp_h=noValue; @@ -216,6 +225,7 @@ char hrf[] = "DEF"; */ RPVersion_POINTER RPVersion; SETPATHdll_POINTER SETPATHdll; +SATSPLNdll_POINTER SATSPLNdll; ABFL1dll_POINTER ABFL1dll; ABFL2dll_POINTER ABFL2dll; ACTVYdll_POINTER ACTVYdll; @@ -320,7 +330,7 @@ RMIX2dll_POINTER RMIX2dll; RDXHMXdll_POINTER RDXHMXdll; PHIXdll_POINTER PHIXdll; PHI0dll_POINTER PHI0dll; - +DQFL2dll_POINTER DQFL2dll; /* * Helper function to split strings the @@ -365,6 +375,23 @@ bool strCompare(const std::string& str1, const std::string& str2) { } +void useSATSPLN(long lerr, char* errormsg) { + // need to check the composition if old . + if (lnc>1) { + if (dxkg[1]>0 && dxkg[1]<1) { + if (dx1kg_old!=dxkg[1]) { + SATSPLNdll(dxmol,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1kg_old = %f\n", dx1kg_old); + printf("dxkg[1] = %f \n", dxkg[1]); + } + } + dx1kg_old=dxkg[1]; + } + } +} + /* @@ -687,6 +714,9 @@ double setFunctionPointers() { } else { // set the pointers // set the pointers, platform independent RPVersion = (RPVersion_POINTER) getFunctionPointer((char *) RPVersion_NAME); + + SATSPLNdll = (SATSPLNdll_POINTER) getFunctionPointer((char *) SATSPLNdll_NAME); + ABFL1dll = (ABFL1dll_POINTER) getFunctionPointer((char *) ABFL1dll_NAME); ABFL2dll = (ABFL2dll_POINTER) getFunctionPointer((char *) ABFL2dll_NAME); ACTVYdll = (ACTVYdll_POINTER) getFunctionPointer((char *) ACTVYdll_NAME); @@ -786,6 +816,8 @@ double setFunctionPointers() { RDXHMXdll = (RDXHMXdll_POINTER) getFunctionPointer((char *) RDXHMXdll_NAME); PHIXdll = (PHIXdll_POINTER) getFunctionPointer((char *) PHIXdll_NAME); PHI0dll = (PHI0dll_POINTER) getFunctionPointer((char *) PHI0dll_NAME); + DQFL2dll = (DQFL2dll_POINTER) getFunctionPointer((char *) DQFL2dll_NAME); + if (debug) printf ("Function pointers set to macro values.\n"); return OK; @@ -1007,6 +1039,24 @@ double getDV_modelica(){ //density of gaseous phase return ddv*dwvap; // mol/l * g/mol = g/l = kg/m3 } +double getHL_modelica(){ + //density of liquid phase + return dhl/dwliq * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} + +double getHV_modelica(){ + //density of gaseous phase + return dhv/dwvap * 1000.0; // J/mol / g/mol * 1000g/kg = J/kg +} +double getSL_modelica(){ + //density of liquid phase + return dsl/dwliq * 1000.0; // J/molK / g/mol * 1000g/kg = J/kgK +} + +double getSV_modelica(){ + //density of gaseous phase + return dsv/dwvap * 1000.0; // J/molK / g/mol * 1000g/kg = J/kgK +} double getQ_modelica(){ if (lnc>1 && abs(dqmol)<990) { // maintain special values @@ -1538,6 +1588,7 @@ int ders_REFPROP(double *ders, char* errormsg, int DEBUGMODE){ // get other sat props at const T,p,x THERM2dll(dt, ddv, dxmolv, spare3, spare4, h_v, s_v, dCv_v, dCp_v, dwm_v,spare2, spare10, spare11, spare12, dxkappa_v, dbeta_v, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); THERM2dll(dt, ddl, dxmoll, spare3, spare4, h_l, s_l, dCv_l, dCp_l, dwm_l,spare2, spare10, spare11, spare12, dxkappa_l, dbeta_l, spare13, spare14, spare15, spare16,spare17, spare18, spare19, spare20, spare21); + //ddv_v = ddv; //ddl_l = ddl; // compute drhodp_h @@ -1870,6 +1921,7 @@ int updateTrns(double *trns, long lerr){ trns[0] = lerr;//error code trns[1] = getETA_modelica(); // dynamic viscosity in Pa.s trns[2] = getTCX_modelica(); // thermal conductivity in W/m.K + trns[3] = dsigma; return 0; } @@ -1892,47 +1944,49 @@ int trns_REFPROP(double *trns, char* errormsg, int DEBUGMODE){ switch(lerr){ case -31: - sprintf(errormsg,"Temperature T=%f out of range for conductivity",dt); + printf(errormsg,"Temperature T=%f out of range for conductivity",dt); break; case -32: - sprintf(errormsg,"density d=%f out of range for conductivity",dd); + printf(errormsg,"density d=%f out of range for conductivity",dd); break; case -33: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); + printf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity",dt,dd); break; case -41: - sprintf(errormsg,"Temperature T=%f out of range for viscosity",dt); + printf(errormsg,"Temperature T=%f out of range for viscosity",dt); break; case -42: - sprintf(errormsg,"density d=%f out of range for viscosity",dd); + printf(errormsg,"density d=%f out of range for viscosity",dd); break; case -43: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); + printf(errormsg,"Temperature T=%f and density d=%f out of range for viscosity",dt,dd); break; case -51: - sprintf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); + printf(errormsg,"Temperature T=%f out of range for conductivity and viscosity",dt); break; case -52: - sprintf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); + printf(errormsg,"density d=%f out of range for conductivity and viscosity",dd); break; case -53: - sprintf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); + printf(errormsg,"Temperature T=%f and density d=%f out of range for conductivity and viscosity",dt,dd); break; case 39: - sprintf(errormsg,"model not found for thermal conductivity"); + printf(errormsg,"model not found for thermal conductivity"); break; case 49: - sprintf(errormsg,"model not found for viscosity"); + printf(errormsg,"model not found for viscosity"); break; case 50: - sprintf(errormsg,"ammonia/water mixture (no properties calculated)"); + printf(errormsg,"ammonia/water mixture (no properties calculated)"); break; case 51: - sprintf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); + printf(errormsg,"exactly at T=%f, rhoc for a pure fluid; k is infinite",dt); break; case -58: + printf(errormsg,"ECS model did not converge"); + break; case -59: - sprintf(errormsg,"ECS model did not converge"); + printf(errormsg,"ECS model did not converge"); break; default: break; @@ -1964,11 +2018,17 @@ int updateProps(double *props, long lerr){ props[13] = getW_modelica(); //speed of sound props[14] = getWML_modelica(); props[15] = getWMV_modelica(); + props[16] = getHL_modelica(); //h of liquid phase + props[17] = getHV_modelica(); //h of vapor phase + props[18] = getSL_modelica(); //s of liquid phase + props[19] = getSV_modelica(); //s of vapor phase + props[20] = dts; //saturation temperature + for (int dim=0; dim=1) { + dqmolLIM=1; + } else { + dqmolLIM=dqmol; + } + + + //printf("dqmol %f\n",dqmol); + //printf("dp %f\n",dp); + //printf("dxmol %f,%f\n",dxmol[0],dxmol[1]); + double pcrit,tcrit,dcrit; + CRITPdll(dxmol,tcrit,pcrit,dcrit,lerr,errormsg,errormessagelength); + //printf("tc %f\n",tcrit); + //printf("pc %f\n",pcrit); + //printf("dc %f\n",dcrit); + + if (dp >= pcrit-0.01) { // critical T or p or both + ENTHALdll(tcrit,dcrit,dxmol,dhl); + ENTROdll(tcrit,dcrit,dxmol,dsl); + dhv=dhl; + dsv=dsl; + dts=tcrit; + ddl=dcrit; + ddv=dcrit; + } else { + if (dqmolLIM == 0.) { // liquid region + long kphsatp=1; + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } + ENTHALdll(dts,ddl,dxmoll,dhl); + ENTROdll(dts,ddl,dxmoll,dsl); + ENTHALdll(dts,ddv,dxmolv,dhv); + ENTROdll(dts,ddv,dxmolv,dsv); + } else if (dqmolLIM == 1.) { // vapor region + long kphsatp=2; + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddl<=ddv) { // compute phase envelope if error occurs, and try again + useSATSPLN(lerr, errormsg); + SATPdll(dp,dxmol,kphsatp,dts,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); + } + ENTHALdll(dts,ddl,dxmoll,dhl); + ENTROdll(dts,ddl,dxmoll,dsl); + ENTHALdll(dts,ddv,dxmolv,dhv); + ENTROdll(dts,ddv,dxmolv,dsv); + } else { // two-phase region + ENTHALdll(dt,ddl,dxmoll,dhl); + ENTROdll(dt,ddl,dxmoll,dsl); + ENTROdll(dt,ddv,dxmolv,dsv); + ENTHALdll(dt,ddv,dxmolv,dhv); + dts=dt; + } + } + + + // some linear interpoltion to avoid strange cp on liquid/vapor lines + if (dqmol>=0 && dqmol<=1) { // two-phase + double dcp_l,dcp_v,spare; + CVCPdll(dt,ddl,dxmoll,spare,dcp_l); + CVCPdll(dt,ddv,dxmolv,spare,dcp_v); + dCp = dcp_l + (dcp_v-dcp_l)*dqmol; + if (calcTrans) { + SURTENdll (dt,ddl,ddv,dxmoll,dxmolv,dsigma,lerr,errormsg,errormessagelength); + } else { + dsigma =0; + } + } else { // single-phase + dsigma = 0; + } + + + updateProps(props, lerr); + if (PartialDersInputChoice!=1) { int outVal = ders_REFPROP(ders,errormsg,debug); if ( 0 != outVal || ders[0] != 0 ) printf("Error in derivative function, returned %i\n",outVal); @@ -2410,10 +2665,13 @@ OUTPUT updateDers(ders, lerr); } +// updateProps(props, lerr); + if (calcTrans) { int outVal = trns_REFPROP(trns,errormsg,debug); if ( 0 != outVal || trns[0] != 0 ) printf("Error in transport property function, returned %i\n",outVal); } + if ( strCompare(out, "p") ) { if (debug) printf("Returning %s = %f\n",out.c_str(),getP_modelica()); return getP_modelica(); @@ -2457,7 +2715,7 @@ OUTPUT //--------------------------------------------------------------------------- -double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double Tsurft, double* x, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ +double satprops_REFPROP(char* what, char* statevar_in, char* fluidnames, double *satprops, double statevarval, double* x, int kph, char* REFPROP_PATH, char* errormsg, int DEBUGMODE, int calcTransport){ /*Calculates thermodynamic saturation properties of a pure substance/mixture, returns both single value and array containing all calculated values (because the are calculated anyway) INPUT: what: character specifying return value (p,T,h,s,d,wm,q,e,w) - Explanation of variables at the end of this function @@ -2475,9 +2733,12 @@ OUTPUT long lerr = 0; + long dkph = kph; + // DEBUGMODE = 1; if (DEBUGMODE) debug = true; + if (calcTransport) calcTrans = true; else calcTrans = false; std::string out = std::string(what).substr(0,1); std::string in1 = std::string(statevar_in).substr(0,1); @@ -2536,72 +2797,145 @@ OUTPUT dpsat = getP_refprop(statevarval); } else if ( strCompare(in1, "t") ) { dtsat = getT_refprop(statevarval); - } - /* else if ( strCompare(in1, "d") ) { - dd = getD_refprop(statevarval); - } */ - else { + } else if ( strCompare(in1, "d") ) { + ddsat = getD_refprop(statevarval); + } else { lerr = 2; sprintf(errormsg,"Unknown state variable: %s\n", in1.c_str()); return lerr; } if (debug) printf("\nstatevar %s checked\n",in1.c_str()); - long j; -/* j--phase flag: 1 = input x is liquid composition (bubble point) - 2 = input x is vapor composition (dew point) - 3 = input x is liquid composition (freezing point) - 4 = input x is vapor composition (sublimation point) -*/ - //long kph = -1; -/* kph--flag specifying desired root for multi-valued inputs - has meaning only for water at temperatures close to its triple point - -1 = return middle root (between 0 and 4 C) - 1 = return highest temperature root (above 4 C) - 3 = return lowest temperature root (along freezing line) */ - double spare1,spare2,spare3,spare4,spare10[ncmax]; + /* + c kph--phase flag: 1 = input x is liquid composition (bubble point) + c 2 = input x is vapor composition (dew point) + c 3 = input x is liquid composition (freezing point) + c 4 = input x is vapor composition (sublimation point) + */ + + double pcrit,tcrit,dcrit; + CRITPdll(dxmolsat,tcrit,pcrit,dcrit,lerr,errormsg,errormessagelength); + if (lerr==0) { if ( strCompare(in1, "t") ) { - j=1; - SATTdll(dtsat,dxmolsat,j,dplsat,ddlsat,spare1,dxmollsat,spare10,lerr,errormsg,errormessagelength); - THERMdll (dtsat,ddlsat,dxmollsat,spare1,spare2,dhlsat,dslsat,dcvlsat,dcplsat,spare3,spare4); - j=2; - SATTdll(dtsat,dxmolsat,j,dpvsat,spare1,ddvsat,spare10,dxmolvsat,lerr,errormsg,errormessagelength); - THERMdll (dtsat,ddvsat,dxmolvsat,spare1,spare2,dhvsat,dsvsat,dcvvsat,dcpvsat,spare3,spare4); - dtlsat=dtsat; - dtvsat=dtsat; - //THERM (t, rho, x, p, e, h, s, cv, cp, w, hjt) + if (dtsat >= tcrit-1) { // critical + ENTHALdll(tcrit,dcrit,dxmolsat,dhlsat); + ENTROdll(tcrit,dcrit,dxmolsat,dslsat); + dhvsat=dhlsat; + dsvsat=dslsat; + dtsat=tcrit; + ddlsat=dcrit; + ddvsat=dcrit; + for (int ii=0;ii1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + SATTdll(dtsat,dxmolsat,dkph,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + } } else if ( strCompare(in1, "p") ) { - j=1; - SATPdll(dpsat,dxmolsat,j,dtlsat,ddlsat,spare1,dxmollsat,spare10,lerr,errormsg,errormessagelength); - THERMdll (dtlsat,ddlsat,dxmollsat,dplsat,spare2,dhlsat,dslsat,dcvlsat,dcplsat,spare3,spare4); - j=2; - SATPdll(dpsat,dxmolsat,j,dtvsat,spare1,ddvsat,spare10,dxmolvsat,lerr,errormsg,errormessagelength); - THERMdll (dtvsat,ddvsat,dxmolvsat,dpvsat,spare2,dhvsat,dsvsat,dcvvsat,dcpvsat,spare3,spare4); - //dplsat=dpsat; - //dpvsat=dpsat; - switch(lerr){ - case 2: - strcpy(errormsg,"P < Ptp"); - break; - case 4: - strcpy(errormsg,"P < 0"); - break; + + if (dpsat >= pcrit-0.01) { // critical + ENTHALdll(tcrit,dcrit,dxmolsat,dhlsat); + ENTROdll(tcrit,dcrit,dxmolsat,dslsat); + dhvsat=dhlsat; + dsvsat=dslsat; + dtsat=tcrit; + ddlsat=dcrit; + ddvsat=dcrit; + for (int ii=0;ii1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + SATPdll(dpsat,dxmolsat,dkph,dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + switch(lerr){ + case 2: + strcpy(errormsg,"P < Ptp"); + break; + case 4: + strcpy(errormsg,"P < 0"); + break; + } } //sprintf(errormsg,"p=%f, h=%f",p ,statevar2); + } else if ( strCompare(in1, "d") ) { + + long dkphsatD=2; + SATDdll(ddsat,dxmolsat,dkphsatD,dkph,dtsat,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + if (lerr!=0 || ddlsat<=ddvsat) { // compute phase envelope if error occurs, and try again + + if (lnc>1) { + if (dxmolsat[1]>0 && dxmolsat[1]<1) { + if (dx1molsat_old!=dxmolsat[1]) { + SATSPLNdll(dxmolsat,lerr,errormsg,errormessagelength); + if (debug) { + printf("\n\n USING SATSPLN, because we have new composition\n\n"); + printf("dx1molsat_old = %f\n", dx1molsat_old); + printf("dxmolsat[1] = %f \n", dxmolsat[1]); + } + } + dx1molsat_old=dxmolsat[1]; + } + } + + SATDdll(ddsat,dxmolsat,dkphsatD,dkph,dtsat,dpsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,lerr,errormsg,errormessagelength); + } + ENTHALdll(dtsat,ddlsat,dxmollsat,dhlsat); + ENTHALdll(dtsat,ddvsat,dxmolvsat,dhvsat); + ENTROdll(dtsat,ddlsat,dxmollsat,dslsat); + ENTROdll(dtsat,ddvsat,dxmolvsat,dsvsat); + + switch(lerr){ + case 2: + strcpy(errormsg,"D > Dmax"); + break; + } + } - /* - else if ( strCompare(in1, "d") ) { - SATDdll(dd,dxmol,j,kph,dt,dp,ddl,ddv,dxmoll,dxmolv,lerr,errormsg,errormessagelength); - switch(lerr){ - case 2: - strcpy(errormsg,"D > Dmax"); - break; - } - } - */ + } switch(lerr){ @@ -2696,13 +3030,9 @@ OUTPUT double dsigma; - if (calcTransport) { - if ( strCompare(in1, "t") ) { - SURTENdll (dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,dsigma,lerr,errormsg,errormessagelength); - } else if ( strCompare(in1, "p") ) { - SURFTdll (Tsurft,ddlsat,dxmollsat,dsigma,lerr,errormsg,errormessagelength); - } - } else { + if (calcTrans) { + SURTENdll (dtsat,ddlsat,ddvsat,dxmollsat,dxmolvsat,dsigma,lerr,errormsg,errormessagelength); + } else { dsigma =0; } @@ -2713,24 +3043,21 @@ OUTPUT //ASSIGN VALUES TO RETURN ARRAY satprops[0] = lerr;//error code - satprops[1] = dtlsat; //Temperature in K - satprops[2] = dtvsat; //Temperature in K - satprops[3] = dplsat*1000; //pressure in kPa->Pa - satprops[4] = dpvsat*1000; //pressure in kPa->Pa - satprops[5] = ddlsat*dwlsat; //density of liquid phase mol/L ->g/L (kg/m3) - satprops[6] = ddvsat*dwvsat; //density of vapor phase mol/L ->g/L (kg/m3) - satprops[7] = dhlsat/dwlsat*1000; //enthalpy of liquid J/mol -> J/g e-3 -> J/kg - satprops[8] = dhvsat/dwvsat*1000; //enthalpy of vapor J/mol -> J/g e-3 -> J/kg - satprops[9] = dslsat/dwlsat*1000; //entropy of liquid J/molK -> J/gK e-3 -> J/kgK - satprops[10] = dsvsat/dwvsat*1000; //entropy of vapor J/molK -> J/gK e-3 -> J/kgK - satprops[11] = dsigma; //surface tension + satprops[1] = dtsat; //Temperature in K + satprops[2] = dpsat*1000; //pressure in kPa->Pa + satprops[3] = ddlsat*dwlsat; //density of liquid phase mol/L ->g/L (kg/m3) + satprops[4] = ddvsat*dwvsat; //density of vapor phase mol/L ->g/L (kg/m3) + satprops[5] = dhlsat/dwlsat*1000; //enthalpy of liquid J/mol -> J/g e-3 -> J/kg + satprops[6] = dhvsat/dwvsat*1000; //enthalpy of vapor J/mol -> J/g e-3 -> J/kg + satprops[7] = dslsat/dwlsat*1000; //entropy of liquid J/molK -> J/gK e-3 -> J/kgK + satprops[8] = dsvsat/dwvsat*1000; //entropy of vapor J/molK -> J/gK e-3 -> J/kgK + satprops[9] = dsigma; //surface tension // satprops[12] = dwlsat/1000; //molecular weight g/mol -> kg/mol // satprops[13] = dwvsat/1000; //molecular weight g/mol -> kg/mol for (int ii=0;ii Date: Mon, 16 Jun 2014 14:01:05 +0200 Subject: [PATCH 55/57] Added transport property methods inside media "NH3_Water" for ammonia-water mixtures --- Media/NH3_Water.mo | 1916 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1916 insertions(+) diff --git a/Media/NH3_Water.mo b/Media/NH3_Water.mo index 7d4a04f..911aed9 100644 --- a/Media/NH3_Water.mo +++ b/Media/NH3_Water.mo @@ -1,6 +1,1922 @@ within REFPROP2Modelica.Media; package NH3_Water "Ammonia and water mixture by REFPROP library" + extends Interfaces.REFPROPMixtureTwoPhaseMedium( final substanceNames={"ammoniaL","water"}, final debugmode=false); + + replaceable function DynamicViscosityLiquid = dynamicViscosity_LIQconde constrainedby + partialDynamicViscosityLiquid; + replaceable function DynamicViscosityVapor = dynamicViscosity_VAPWilke constrainedby + partialDynamicViscosityVapor; + replaceable function ThermalConductivityLiquid = thermalConductivity_LIQConde + constrainedby + partialThermalConductivityLiquid; + replaceable function ThermalConductivityVapor = thermalConductivity_VAPWilke constrainedby + partialThermalConductivityVapor; + +/* + type ViscLiq = enumeration( + Conde "Conde 2006", + ElSayed "El-Sayed 1988", + HdbKaltetechnik "Handbuch der Kältetechnik", + SteccoDesideri "Stecco and Desideri 1991", + TejaRice "Teja and Rice (in Poling 2001)", + TejaRiceSassen "Teja and Rice using Sassen critical props", + TejaRiceFit "Teja and Rice (fit others with psi=1.6)") + "Liquid viscosity methods"; + constant ViscLiq viscLiq = ViscLiq.Conde annotation(evaluate=true); + + type ViscVap = enumeration( + Wilke "Wilke (in Poling 2001)", + Reichenberg "Reichenberg (in Poling 2001)", + Chung "Chung et al. (in Poling 2001)", + ChungErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)") + "Vapor viscosity methods"; + constant ViscVap viscVap = ViscVap.Wilke; + + type CondLiq = enumeration( + Conde "Conde 2006", + ElSayed "El-Sayed 1988", + Filippov "Filippov (in Poling 2001)", + Jamieson "(in Poling 2001)") "Liquid conductivity methods"; + constant CondLiq condLiq = CondLiq.Conde; + + type CondVap = enumeration( + Average "Mole-fraction average (suggested in Poling 2001)", + MasonSaxena "Mason and Saxena (in Poling 2001)", + Chung "Chung et al. (in Poling 2001)", + ChungErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)") + "Vapor conductivity methods"; + constant CondVap condVap = CondVap.Average; +*/ + + function criticalProperties + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Modelica.SIunits.Temperature Tc "critical temperature"; + output Modelica.SIunits.Pressure pc "critical pressure"; + output Modelica.SIunits.Density dc "critical density"; + output MoleFraction[nX] Z "mole fraction"; + + protected + Real[3 + 1*nX] critprops; + String errormsg=StrJoin(fill("xxxx", 64), ""); + + package Internal + function InternalFunction + input String fluidnames; + input Real[:] critprops; + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + input String errormsg; + output Real val; + + external "C" val= critprops_REFPROP( + fluidnames, + critprops, + X, + REFPROP_PATH, + errormsg, + debugmode) annotation (Include="#include ", Library="refprop_wrapper"); + annotation(Inline=true); + end InternalFunction; + end Internal; + + algorithm + Internal.InternalFunction( + fluidnames, + critprops, + X, + errormsg); + + Tc:=critprops[1]; + pc:=critprops[2]; + dc:=critprops[3]; + Z:=critprops[4:4+nX-1]; + + annotation(Inline=true,LateInline=true); + end criticalProperties; + + redeclare function dynamicViscosity + "Return dynamic viscosity, LIQ=CONDE, VAP=WILKE" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + algorithm + if state.q<=0.01 then // liquid + eta := DynamicViscosityLiquid(state); + elseif state.q>=0.99 then // vapor + eta := DynamicViscosityVapor(state); + else // twophase + eta:=1e-6; + end if; + + end dynamicViscosity; + + redeclare function thermalConductivity + "Return thermal conductivity, LIQ=Jamison, VAP=MOLE FRACTION AVG" + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda "thermal conductivity"; + + algorithm + if state.q <= 0.01 then + // liquid + lambda :=ThermalConductivityLiquid(state); + elseif state.q >= 0.99 then + // vapor + lambda :=ThermalConductivityVapor(state); + else + // twophase + lambda := 1e-6; + end if; + + end thermalConductivity; + + function criticalProperties_sassen1990 + input MassFraction X[:] "mass fraction m_NaCl/m_Sol"; + output Modelica.SIunits.Temperature Tc "critical temperature"; + output Modelica.SIunits.Pressure pc "critical pressure"; + // output Modelica.SIunits.Density dc "critical density"; + output MoleFraction[nX] Z "mole fraction"; + + protected + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + + algorithm + Z[1] :=X[1]/(X[1] + (Ma*(1 - X[1])/Mw)); + Z[2] :=(1 - X[1])/((1 - X[1]) + ((X[1]*Mw)/Ma)); + + Tc :=647.14 - 199.822371*Z[1] + 109.035522*Z[1]^2 - 239.626217*Z[1]^3 + 88.689691*Z[1]^4; + pc :=220.64*1e5 - 37.923795*1e5*Z[1] + 36.424739*1e5*Z[1]^2 -41.851597*1e5*Z[1]^3 -63.805617*1e5*Z[1]^4; + + annotation(Inline=true,LateInline=true); + end criticalProperties_sassen1990; + + partial function partialDynamicViscosityLiquid + end partialDynamicViscosityLiquid; + + function dynamicViscosity_LIQconde "Conde 2006" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + Real F1; + Real F2; + Real F12; + Real F21; + + Real F_x; + Real DELTAeta; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := max(195.5,state.T*Tc_a/Tc) "Corresponding temp. for ammonia, K"; + Tcorr_w := max(273.16,state.T*Tc_w/Tc) "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + state_a :=setState_TqX( + min(Tc_a-1,Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w :=setState_TqX( + min(Tcorr_w,Tc_w-1), + 0, + {0,1}, + calcTransport=true); + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + if debugmode then + Modelica.Utilities.Streams.print("got (mu_a,mu_w,lambda_a,lambda_w), (" + String(mu_a) + "," + String(mu_w) + ")"); + end if; + + mu_a := mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; //convert to (1e-6 Pa.s) + + F_x :=6.38*((1 - Z[1])^(1.125*Z[1]))*(1 - exp(-0.585*Z[1]*(1 - Z[1])^0.18))* + log((mu_a^0.5)*(mu_w^0.5)); + DELTAeta:=(0.534 - 0.815*(state.T/Tc_w))*F_x; + eta :=exp(Z[1]*log(mu_a) + (1 - Z[1])*log(mu_w) + DELTAeta); + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_LIQconde; + + function dynamicViscosity_LIQelsayed + "El-Sayed 1988 (correct equations by Thorin 2001)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + Real F1; + Real F2; + Real F12; + Real F21; + + Real F_x; + Real F_t; + Real DELTAeta; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + Tcorr_a := max(195.5,state.T*Tc_a/Tc) "Corresponding temp. for ammonia, K"; + Tcorr_w := max(273.16,state.T*Tc_w/Tc) "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + state_a :=setState_TqX( + min(Tc_a-1,Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w :=setState_TqX( + min(Tcorr_w,Tc_w-1), + 0, + {0,1}, + calcTransport=true); + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + if debugmode then + Modelica.Utilities.Streams.print("got (mu_a,mu_w,lambda_a,lambda_w), (" + String(mu_a) + "," + String(mu_w) + ")"); + end if; + + mu_a := mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; //convert to (1e-6 Pa.s) + + F_x:=(Z[1]*Z[2] - 0.125*(Z[1]^2)*Z[2])*((log(mu_a*mu_w))^0.5); + F_t:=4.219 - 3.7996*(state.T*(9/5)/492) + 0.842*(state.T*(9/5)/492)^2; + F12:=F_t*F_x; + eta :=(exp(Z[1]*log(mu_a) + Z[2]*log(mu_w) + F12)); + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_LIQelsayed; + + function dynamicViscosity_LIQHDK "Handbuch der Kältetechnik" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + algorithm + eta :=(10^(10^((2000/(500 + state.T - 273.15)) - 4.41 + 0.925*state.X[1] - 1.743* + state.X[1]^2 + 0.021*state.X[1]^3)) - 1)*1e-3; + + end dynamicViscosity_LIQHDK; + + function dynamicViscosity_LIQTejeRice "Teja and Rice (in Poling 2001)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 1;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,Tc[1]/Tcm*state.T); + T_j := max(273.16,Tc[2]/Tcm*state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRice; + + function dynamicViscosity_LIQTejeRiceSteccoWay "Stecco and Desideri 1991" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 8;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,state.T); + T_j := max(273.16,state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceSteccoWay; + + function dynamicViscosity_LIQTejeRiceSassensTcrit + "Teja and Rice using Sassen critical props" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tcm:=Tc_actual; + T_i := max(195.5,state.T*Tc[1]/Tc_actual) + "Corresponding temp. for ammonia, K"; + T_j := max(273.16,state.T*Tc[2]/Tc_actual) + "Corresponding temp. for water, K"; + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceSassensTcrit; + + function dynamicViscosity_LIQTejeRiceFit + "Teja and Rice (fit others with psi=1.6)" + extends partialDynamicViscosityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState states[2]; + + Modelica.SIunits.Temperature Tc_actual "critical temperature"; + Modelica.SIunits.Pressure pc_actual "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + + Modelica.SIunits.DynamicViscosity etas[2]; + + Real yi,yj,psi_ij,epsilon_i,epsilon_j,Vc_ij,Vcm, Tc_ij, Tcm, T_i, T_j, M_m, epsilon_m; + + algorithm + (Tc_actual,pc_actual,Z) :=criticalProperties_sassen1990(state.X); + + yi := Z[1]; + yj := Z[2]; + + psi_ij := 1.6;// 8 as suggested by el-sayed??? + + epsilon_i := Vc[1]^(2/3)/(Tc[1]*MM[1])^0.5; // "9-13.18" + epsilon_j := Vc[2]^(2/3)/(Tc[2]*MM[2])^0.5; // "9-13.18" + + Vc_ij := (Vc[1]^(1/3) + Vc[2]^(1/3))^3/8; + // "9-13.23" + Vcm := yi*yi*Vc[1] + yj*yj*Vc[2] + 2*yi*yj*Vc_ij; // "9-13.19" + + Tc_ij := psi_ij*(Tc[1]*Tc[2]*Vc[1]*Vc[2])^0.5/Vc_ij; // "9-13.24" + Tcm := (yi*yi*Tc[1]*Vc[1] + yj*yj*Tc[2]*Vc[2] + 2*yi*yj*Tc_ij*Vc_ij)/Vcm; // "9-13.19" + + T_i := max(195.5,Tc[1]/Tcm*state.T); + T_j := max(273.16,Tc[2]/Tcm*state.T); + + states[1] := setState_TqX( + min(Tc[1]-1,T_i), + 0, + {1,0}, + calcTransport=true); + states[2] := setState_TqX( + min(T_j,Tc[2]-1), + 0, + {0,1}, + calcTransport=true); + etas[1] := states[1].eta; + etas[2] := states[2].eta; + + M_m :=yi*MM[1] + yj*MM[2]; // "9-13.21" + epsilon_m :=Vcm^(2/3)/(Tcm*M_m)^0.5; // "9-13.18" + + eta :=exp(yi*log(etas[1]*epsilon_i) + yj*log(etas[2]*epsilon_j))/epsilon_m; // "9-13.25" + + end dynamicViscosity_LIQTejeRiceFit; + + partial function partialDynamicViscosityVapor + end partialDynamicViscosityVapor; + + function dynamicViscosity_VAPReichenberg "Reichenberg (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_w; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + constant Modelica.SIunits.Pressure pc_a = 11333000; + constant Modelica.SIunits.Pressure pc_w = 22064000; + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + constant Real mu_1 = 1.470; // dipole moment + constant Real mu_2 = 1.855; // dipole moment + + Modelica.SIunits.DynamicViscosity eta_a; + Modelica.SIunits.DynamicViscosity eta_w; + + Real Tr_1; + Real Tr_2; + Real Tr_12; + Real mu_r1; + Real mu_r2; + Real mu_r12; + Real U_1; + Real U_2; + Real C_1; + Real C_2; + Real H_12; + Real K_1; + Real K_2; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w-1 then // + sat_w := setSat_TX(state.T, {0,1}); + state_w :=setState_pTX( + min(state.p,sat_w.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_w :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + eta_a :=state_a.eta; + eta_w :=state_w.eta; + + eta_a:=eta_a*1e6; //convert to (1e-6 Pa.s) + eta_w:=eta_w*1e6; //convert to (1e-6 Pa.s) + + Tr_1 := state.T/Tc_a "Reduced temperature of ammonia"; + Tr_2 := state.T/Tc_w "Reduced temperature of water"; + Tr_12 := state.T/(sqrt(Tc_a*Tc_w)); + mu_r1:=52.46*(((mu_1^2)*pc_a)/Tc_a^2); + mu_r2:=52.46*(((mu_2^2)*pc_w)/Tc_w^2); + mu_r12:=sqrt(mu_r1*mu_r2); + U_1:=(((1 + 0.36*Tr_1*(Tr_1 - 1))^(1/6))/sqrt(Tr_1))*(((Tr_1^3.5) + (10* + mu_r1)^7)/((Tr_1^3.5)*(1 + (10*mu_r1)^7))); + U_2:=(((1 + 0.36*Tr_2*(Tr_2 - 1))^(1/6))/sqrt(Tr_2))*(((Tr_2^3.5) + (10* + mu_r2)^7)/((Tr_2^3.5)*(1 + (10*mu_r2)^7))); + C_1:=(Ma^(1/4))/sqrt(eta_a*U_1); + C_2:=(Mw^(1/4))/sqrt(eta_w*U_2); + H_12:= (sqrt((Ma*Mw)/32)/((Ma+Mw)^(3/2)))*(((1+0.36*Tr_12*(Tr_12-1))^(1/6))/sqrt(Tr_12))*((C_1+C_2)^2)*(((Tr_12^3.5)+(10*mu_r12)^7)/((Tr_12^3.5)*(1+(10*mu_r12)^7))); + K_1:=(Z[1]*eta_a)/(Z[1]+eta_a*(Z[2]*H_12*(3+2*(Mw/Ma)))); + K_2:=(Z[2]*eta_w)/(Z[2]+eta_w*(Z[1]*H_12*(3+(2*Ma/Mw)))); + eta:=(K_1*(1+H_12^2*K_2^2)+K_2*(1+2*H_12*K_1+H_12^2*K_1^2)); + + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_VAPReichenberg; + + function dynamicViscosity_VAPWilke "Wilke (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_w; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + constant Modelica.SIunits.Pressure pc_a = 11333000; + constant Modelica.SIunits.Pressure pc_w = 22064000; + constant Real Mw=18.0153; // Molar mass of water, g/mol + constant Real Ma=17.0305; // Molar mass of ammonia, g/mol + + Real F12,F21; + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.DynamicViscosity mu_w; + + algorithm + (Tc,pc,Z) :=criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w-1 then // + sat_w := setSat_TX(state.T, {0,1}); + state_w :=setState_pTX( + min(state.p,sat_w.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_w :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + mu_a :=state_a.eta; + mu_w :=state_w.eta; + + mu_a:=mu_a*1e6; //convert to (1e-6 Pa.s) + mu_w:=mu_w*1e6; //convert to (1e-6 Pa.s) + + F12 := ((1 + (sqrt(mu_a/mu_w)*((Mw/Ma)^0.25)))^2)/sqrt(8*(1 + (Ma/Mw))); + F21 := F12*(mu_w/mu_a)*(Ma/Mw); + eta:= ((mu_a*Z[1])/(Z[1] + (F12*Z[2]))) + ((mu_w*Z[2])/(Z[2] + (F21*Z[1]))); // Mixture vapour dynamic visc., microPa s, Thorin, 2001 + eta := eta/1e6; // convert to Pa.s + + end dynamicViscosity_VAPWilke; + + function dynamicViscosity_VAPChung "Chung et al. (in Poling 2001)" + extends partialDynamicViscosityVapor; + + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y, G1, G2, eta_star_star, eta_star; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + // eta :=26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v); // "1e-6 poise unit = 1-7 " "9-5.24" + // eta := eta/10^7; // from "mu poise" to "Pa s" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // we always have liquid or vapor, no two-phase + + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + y :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); // "9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star_m^(-1) + E[10]*T_star_m^(-2)); // "9-6.23" + eta_star :=T_star_m^0.5/OMEGA_v*F_cm*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta := eta_star*36.344*(M_m*Tcm)^0.5/Vcm^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + + end dynamicViscosity_VAPChung; + + function dynamicViscosity_VAPChungPureErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)" + extends partialDynamicViscosityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output DynamicViscosity eta "Dynamic viscosity"; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y, G1, G2, eta_star_star, eta_star; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + ThermodynamicState state_2,state_1; + SaturationProperties sat_2; + Real eta_1,eta_2, eta_1actual,eta_2actual; + + package Pure + function eta + + input Real DM; + input Real Vc; + input Real Tc; + input Real omega; + input Real kappa; + input Real MM; + input Real T; + input Real rho; + + output Real eta; + + protected + Real DM_r,F_c,T_star, y, G1, G2, eta_star_star, eta_star, OMEGA_v; + Real E[10]; + + constant Real a[10] = {6.324,1.210e-3,5.283,6.623,19.745,-1.900,24.275,0.7972,-0.2382,0.06863}; + constant Real b[10] = {50.412,-1.154e-3,254.209,38.096,7.630,-12.537,3.450,1.117,0.06770,0.3479}; + constant Real c[10] = {-51.680,-6.257e-3,-168.48,-8.464,-14.354,4.985,-11.291,0.01235,-0.8163,0.5926}; + constant Real d[10] = {1189.0,0.03728,3898.0,31.42,31.53,-18.15,69.35,-4.117,4.025,-0.727}; + + algorithm + // "! pure values used for error weighting" + DM_r :=131.3*DM/(Vc*Tc)^0.5; // "9-4.12" + F_c :=1 - 0.2756*omega + 0.059035*DM_r^4 + kappa; // "9-4.11" + T_star :=1.2593*T/Tc; // "9-4.9" + OMEGA_v:=1.16145*T_star^(-0.14874) + 0.52487*exp(-0.77320*T_star) + 2.16178 + *exp(-2.43787*T_star); // "9-4.3" + + y :=rho*Vc/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega + c[i]*DM_r^4 + d[i]*kappa; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); //"9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star^(-1) + E[10]*T_star^(-2)); // "9-6.23" + eta_star :=T_star^0.5/OMEGA_v*F_c*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta :=eta_star*36.344*(MM*Tc)^0.5/Vc^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + end eta; + + end Pure; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + // eta :=26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v); // "1e-6 poise unit = 1-7 " "9-5.24" + // eta := eta/10^7; // from "mu poise" to "Pa s" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // we always have liquid or vapor, no two-phase + + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + y :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:10 loop + E[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(E[1]*((1 - exp(-E[4]*y))/y) + E[2]*G1*exp(E[5]*y) + E[3]*G1)/(E[1]*E[4] + + E[2] + E[3]); // "9-6.22" + eta_star_star :=E[7]*y^2*G2*exp(E[8] + E[9]*T_star_m^(-1) + E[10]*T_star_m^(-2)); // "9-6.23" + eta_star :=T_star_m^0.5/OMEGA_v*F_cm*(G2^(-1) + E[6]*y) + eta_star_star; // "9-6.19" + eta := eta_star*36.344*(M_m*Tcm)^0.5/Vcm^(2/3); // "9-6.18" + eta := eta/10^7; // from "mu poise" to "Pa s" + + // error weighting + // get corresponding values of pure components + + state_1 :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + if state.T < Tc[2]-1 then // + sat_2 := setSat_TX(state.T, {0,1}); + state_2 :=setState_pTX( + min(state.p,sat_2.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_2 :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + // if state.p < 22064000 then + // sat_2 := setSat_pX(state.p, {0,1}); + // state_2 :=setState_pTX( + // state.p, + // max(state.T,sat_2.Tsat+0.1), + // {0,1}, + // calcTransport=true); + // else + // state_2 :=setState_pTX( + // state.p, + // state.T, + // {0,1}, + // calcTransport=true); + // end if; + + eta_1 :=Pure.eta( + DM[1], + Vc[1], + Tc[1], + omega[1], + kappa[1], + MM[1], + state.T, + rho); // using mixture rho to do the averaging + eta_2 :=Pure.eta( + DM[2], + Vc[2], + Tc[2], + omega[2], + kappa[2], + MM[2], + state.T, + rho); // using mixture rho to do the averaging + + // Modelica.Utilities.Streams.print("got eta_1 = " + String(eta_1)); + // Modelica.Utilities.Streams.print("got state_1.eta = " + String(state_1.eta)); + // Modelica.Utilities.Streams.print("got eta_2 = " + String(eta_2)); + // Modelica.Utilities.Streams.print("got state_2.eta = " + String(state_2.eta)); + + eta := eta + (state_1.eta-eta_1)*yi + (state_2.eta-eta_2)*yj; + + end dynamicViscosity_VAPChungPureErrorWeight; + + partial function partialThermalConductivityVapor + end partialThermalConductivityVapor; + + function thermalConductivity_VAPWilke "Mason and Saxena (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + SaturationProperties sat_w; + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Real Mw=18.0153; + // Molar mass of water, g/mol + constant Real Ma=17.0305; + // Molar mass of ammonia, g/mol + + Modelica.SIunits.DynamicViscosity mu_a; + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.DynamicViscosity mu_w; + Modelica.SIunits.ThermalConductivity lambda_w; + + Real F12; + Real F21; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a := setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w - 1 then + // + sat_w := setSat_TX(state.T, {0,1}); + state_w := setState_pTX( + min(state.p, sat_w.psat - 1), + state.T, + {0,1}, + calcTransport=true); + else + state_w := setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + mu_a := state_a.eta; + mu_w := state_w.eta; + + mu_a := mu_a*1e6; + //convert to (1e-6 Pa.s) + mu_w := mu_w*1e6; + //convert to (1e-6 Pa.s) + + F12 := ((1 + (sqrt(mu_a/mu_w)*((Mw/Ma)^0.25)))^2)/sqrt(8*(1 + (Ma/Mw))); + F21 := F12*(mu_w/mu_a)*(Ma/Mw); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := ((lambda_a*Z[1])/(Z[1] + (F12*Z[2]))) + ((lambda_w*Z[2])/(Z[2] + ( + F21*Z[1]))); + + // Mixture vapour th. cond., W/(m K), Thorin, 2001 + + end thermalConductivity_VAPWilke; + + function thermalConductivity_VAPLinearMolePoling + "Mole-fraction average (suggested in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + SaturationProperties sat_w; + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + // it will always be vapor or supercritical! + state_a := setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + + if state.T < Tc_w - 1 then + // + sat_w := setSat_TX(state.T, {0,1}); + state_w := setState_pTX( + min(state.p, sat_w.psat - 1), + state.T, + {0,1}, + calcTransport=true); + else + state_w := setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_VAPLinearMolePoling; + + function thermalConductivity_VAPChung "Chung et al. (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + Real Cv[2]; // ideal gas specfic volume + constant Real beta[2] = {1.08^(-1),0.78^(-1)}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y_m, G1, G2, q, PSI_m, alpha_m, beta_m, Z_m, C_vm; + Real B[7]; + Real eta_m0, lambda_m0; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + // first mix visc + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + eta_m0 := 26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v) * 1e-7; // "1e-6 poise unit = 1-7 " "9-5.24" + + // second mix cond + + Cv[1] :=(4.238 - 4.215e-3*state.T + 2.041e-5*state.T^2 - 2.126*1e-8*state.T^3 + + 0.761e-11*state.T^4)*8.314 - 8.314; + Cv[2] :=(4.395 - 4.186e-3*state.T + 1.405e-5*state.T^2 - 1.564*1e-8*state.T^3 + + 0.632e-11*state.T^4)*8.314 - 8.314; + C_vm :=yi*Cv[1] + yj*Cv[2]; // "10-6.6" + alpha_m :=C_vm/8.314 - 1.5;// "10-3.14" + //beta_m = 0.7862 - 0.7109*omega_m + 1.3168*omega_m^2 "10-3.14" + /* + For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and + is not available,use a default value of (1.32)^(-1)=0.758 + "! how to deal with beta_m for polar mixtures???????" + "! I would choose similar mixture rules as for sigma, epsilon and kappa how to deal with beta_m for polar mixtures???????" + */ + beta_m :=yi*yi*beta[1] + yj*yj*beta[2] + 2*yi*yj*(beta[1]*beta[2])^0.5; + Z_m :=2 + 10.5*(state.T/Tcm)^2; // "10-3.14" + PSI_m :=1 + alpha_m*(0.215 + 0.28288*alpha_m - 1.061*beta_m + 0.26665*Z_m)/(0.6366 + + beta_m*Z_m + 1.061*alpha_m*beta_m); // "10-3.14" + lambda_m0 :=3.75*PSI_m/(C_vm/8.314)*eta_m0*C_vm/(M_m*1e-3); // "10-3.14" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // //this is just to make sure calculation is done right (is gas) if two-phase.. + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + + y_m :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y_m)/(1 - y_m)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y_m))/y_m) + B[2]*G1*exp(B[5]*y_m) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); // "9-6.22" + + q :=3.586e-3*(Tcm/(M_m*1e-3))^0.5/Vcm^(2/3); + lambda :=31.2*eta_m0*PSI_m/(M_m*1e-3)*(G2^(-1) + B[6]*y_m) + q*B[7]*y_m^2*(state.T/ + Tcm)^0.5*G2; // "10-5.5" + + end thermalConductivity_VAPChung; + + function thermalConductivity_VAPChungPureErrorWeight + "Chung et al. incl. mole-fraction avg. error correction (in Poling 2001)" + extends partialThermalConductivityVapor; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + constant Modelica.SIunits.Temperature Tc[2] = {405.560,647.096}; // critical T, K + constant Real MM[2]= {17.0305,18.0153}; // Molar mass, kg/kmol + // constant Real DM[2] = {1.470,1.855}; // dipole moment, debye + constant Real DM[2] = {1.5,1.8}; // dipole moment, debye + constant Real omega[2] = {0.2558,0.3443}; // accentric factor + constant Real Vc[2] = {75.6889,55.9536}; // critical volume, mol/cm3 + constant Real kappa[2] = {0.0,0.076}; // hydrogen bonding or hydrogen association factor + Real Cv[2]; // ideal gas specfic volume + constant Real beta[2] = {1.08^(-1),0.78^(-1)}; // hydrogen bonding or hydrogen association factor + + Modelica.SIunits.Temperature Tc_dum "critical temperature"; + Modelica.SIunits.Pressure pc_dum "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + Real yi,yj; + + Real sigma_i,sigma_j,sigma_ij,sigma_m; + Real epsilon_i_K,epsilon_j_K,epsilon_ij_K,epsilon_m_K; + Real M_ij,M_m,omega_ij,omega_m; + Real DM_m, Vcm, Tcm, DM_rm, kappa_m, F_cm, T_star_m, OMEGA_v; + Real MMm, rho, y_m, G1, G2, q, PSI_m, alpha_m, beta_m, Z_m, C_vm; + Real B[7]; + Real eta_m0, lambda_m0; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + + ThermodynamicState state_1,state_2; + SaturationProperties sat_2; + Real lambda_1,lambda_2,lambda_1actual,lambda_2actual; + + package Pure + function lambda + + input Real DM; + input Real Vc; + input Real Tc; + input Real omega; + input Real kappa; + input Real MM; + input Real T; + input Real rho; + input Real Cv; + input Real beta; + + output Real lambda; + + protected + Real DM_r,F_c,T_star, y, G1, G2, eta_star_star, eta_star, OMEGA_v; + Real B[7]; + + Real eta_0,lambda_0,PSI,Z,alpha,q; + + constant Real a[7] = {2.4166,-0.50924,6.6107,14.543,0.79274,-5.8634,91.089}; + constant Real b[7] = {0.74824,-1.5094,5.6207,-8.9139,0.82019,12.801,128.11}; + constant Real c[7] = {-0.91858,-49.991,64.76,-5.6379,-0.69369,9.5893,-54.217}; + constant Real d[7] = {121.72,69.983,27.039,74.344,6.3173,65.529,523.81}; + algorithm + // "! pure values used for error weighting" + DM_r :=131.3*DM/(Vc*Tc)^0.5; // "9-4.12" + F_c :=1 - 0.2756*omega + 0.059035*DM_r^4 + kappa; // "9-4.11" + T_star :=1.2593*T/Tc; // "9-4.9" + OMEGA_v:=1.16145*T_star^(-0.14874) + 0.52487*exp(-0.77320*T_star) + 2.16178 + *exp(-2.43787*T_star); // "9-4.3" + + eta_0 :=(40.785*F_c*(MM*T)^0.5/(Vc^(2/3)*OMEGA_v))*1e-7; // "1e-6 poise unit = 1-7 " "9-4.10" + + //"! Then thermal conductivity by Chung" + alpha :=Cv/8.314 - 1.5; + Z :=2 + 10.5*(T/Tc)^2; + PSI:=1 + alpha*(0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z)/(0.6366 + + beta*Z + 1.061*alpha*beta); + lambda_0 :=3.75*PSI/(Cv/8.314)*eta_0*Cv/(MM*1e-3); // "10-3.14" + + /* +For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and +is not available,use a default value of (1.32)^(-1)=0.758 +*/ + y :=rho*Vc/6; // "9-6.20" + G1 :=(1 - 0.5*y)/(1 - y)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega + c[i]*DM_r^4 + d[i]*kappa; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y))/y) + B[2]*G1*exp(B[5]*y) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); //"9-6.22" + + q :=3.586e-3*(Tc/(MM*1e-3))^0.5/Vc^(2/3); + lambda :=31.2*eta_0*PSI/(MM*1e-3)*(G2^(-1) + B[6]*y) + q*B[7]*y^2*(T/Tc)^0.5* + G2; // "10-5.5" + + end lambda; + + end Pure; + + algorithm + (Tc_dum,pc_dum,Z) :=criticalProperties_sassen1990(state.X); + + yi :=Z[1]; + yj :=Z[2]; + + // first mix visc + sigma_i:=0.809*Vc[1]^(1/3); // "9-5.32"; + sigma_j:=0.809*Vc[2]^(1/3); // "9-5.32" + sigma_ij:=(sigma_i*sigma_j)^0.5; // "9-5.33" + sigma_m :=(yi*yi*sigma_i^3 + yj*yj*sigma_j^3 + 2*yi*yj*sigma_ij^3)^(1/3); // "9-5.24" + + epsilon_i_K :=Tc[1]/1.2593; // "9-5.34" + epsilon_j_K :=Tc[2]/1.2593; // "9-5.34" + epsilon_ij_K :=(epsilon_i_K*epsilon_j_K)^0.5; // "9-5.35" + epsilon_m_K :=(yi*yi*epsilon_i_K*sigma_i^3 + yj*yj*epsilon_j_K*sigma_j^3 + 2* + yi*yj*epsilon_ij_K*sigma_ij^3)/sigma_m^3; // "9-5.27" + + M_ij :=2*MM[1]*MM[2]/(MM[1] + MM[2]); // "9-5.40" + M_m :=((yi*yi*epsilon_i_K*sigma_i^2*MM[1]^0.5 + yj*yj*epsilon_j_K*sigma_j^2* + MM[2]^0.5 + 2*yi*yj*epsilon_ij_K*sigma_ij^2*M_ij^0.5)/(epsilon_m_K*sigma_m^2)) + ^2; // "9-5.28" + + omega_ij:=(omega[1] + omega[2])/2; + omega_m :=(yi*yi*omega[1]*sigma_i^3 + yj*yj*omega[2]*sigma_j^3 + 2*yi*yj* + omega_ij*sigma_ij^3)/sigma_m^3; // "9-5.29" + + DM_m :=(sigma_m^3*(yi*yi*DM[1]^4/sigma_i^3 + yj*yj*DM[2]^4/sigma_j^3 + 2*yi* + yj*DM[1]^2*DM[2]^2/sigma_ij^3))^(1/4); // "9-5.30" + Vcm :=(sigma_m/0.809)^3; // "9-5.44" + Tcm :=1.2593*epsilon_m_K; // "9-5.42" + DM_rm :=131.3*DM_m/(Vcm*Tcm)^0.5; // "9-5.43" + kappa_m :=yi*yi*kappa[1] + yj*yj*kappa[2] + 2*yi*yj*(kappa[1]*kappa[2])^0.5; // "9-5.31" + F_cm :=1 - 0.275*omega_m + 0.059035*DM_rm^4 + kappa_m; // "9-5.41" + + T_star_m := state.T/epsilon_m_K; + OMEGA_v:=1.16145*T_star_m^(-0.14874) + 0.52487*exp(-0.77320*T_star_m) + 2.16178 + *exp(-2.43787*T_star_m); // "9-4.3" + + eta_m0 := 26.69*F_cm*(M_m*state.T)^0.5/(sigma_m^2*OMEGA_v) * 1e-7; // "1e-6 poise unit = 1-7 " "9-5.24" + + // second mix cond + + Cv[1] :=(4.238 - 4.215e-3*state.T + 2.041e-5*state.T^2 - 2.126*1e-8*state.T^3 + + 0.761e-11*state.T^4)*8.314 - 8.314; + Cv[2] :=(4.395 - 4.186e-3*state.T + 1.405e-5*state.T^2 - 1.564*1e-8*state.T^3 + + 0.632e-11*state.T^4)*8.314 - 8.314; + C_vm :=yi*Cv[1] + yj*Cv[2]; // "10-6.6" + alpha_m :=C_vm/8.314 - 1.5;// "10-3.14" + //beta_m = 0.7862 - 0.7109*omega_m + 1.3168*omega_m^2 "10-3.14" + /* + For polar materials beta is specific for each compound; Chung, et al. (1984) list values for a few materials. If the compound is polar and + is not available,use a default value of (1.32)^(-1)=0.758 + "! how to deal with beta_m for polar mixtures???????" + "! I would choose similar mixture rules as for sigma, epsilon and kappa how to deal with beta_m for polar mixtures???????" + */ + beta_m :=yi*yi*beta[1] + yj*yj*beta[2] + 2*yi*yj*(beta[1]*beta[2])^0.5; + Z_m :=2 + 10.5*(state.T/Tcm)^2; // "10-3.14" + PSI_m :=1 + alpha_m*(0.215 + 0.28288*alpha_m - 1.061*beta_m + 0.26665*Z_m)/(0.6366 + + beta_m*Z_m + 1.061*alpha_m*beta_m); // "10-3.14" + lambda_m0 :=3.75*PSI_m/(C_vm/8.314)*eta_m0*C_vm/(M_m*1e-3); // "10-3.14" + + // Modelica.Utilities.Streams.print("got OMEGA_v = " + String(OMEGA_v)); + // Modelica.Utilities.Streams.print("got sigma_m = " + String(sigma_m)); + // Modelica.Utilities.Streams.print("got epsilon_m_K = " + String(epsilon_m_K)); + // Modelica.Utilities.Streams.print("got M_m = " + String(M_m)); + // Modelica.Utilities.Streams.print("got omega_m = " + String(omega_m)); + // Modelica.Utilities.Streams.print("got DM_rm = " + String(DM_rm)); + + // "extention to dense (high pressure)" + + MMm :=yi*MM[1] + yj*MM[2]; + + // this is just to make sure calculation is done right (is gas) if two-phase.. + // if state.q <= 1 and state.q>=0 then // two-phase state + // rho :=state.sat.dv/(MMm*1e-3)/(1e6); // from kg/m3 to mol/cm3 + // //rho = state.dv / (MMm * 1e-3 [kmol/mol]) / (1e6 [cm^3/m^3]) + // //{rho=0.000001} + // else + rho:=state.d/(MMm*1e-3)/(1e6);// from kg/m3 to mol/cm3 + // end if; + + y_m :=rho*Vcm/6; // "9-6.20" + G1 :=(1 - 0.5*y_m)/(1 - y_m)^3; // "9-6.21" + for i in 1:7 loop + B[i] :=a[i] + b[i]*omega_m + c[i]*DM_rm^4 + d[i]*kappa_m; + end for; + G2 :=(B[1]*((1 - exp(-B[4]*y_m))/y_m) + B[2]*G1*exp(B[5]*y_m) + B[3]*G1)/(B[1]*B[4] + + B[2] + B[3]); // "9-6.22" + + q :=3.586e-3*(Tcm/(M_m*1e-3))^0.5/Vcm^(2/3); + lambda :=31.2*eta_m0*PSI_m/(M_m*1e-3)*(G2^(-1) + B[6]*y_m) + q*B[7]*y_m^2*(state.T/ + Tcm)^0.5*G2; // "10-5.5" + + // error weighting + // get corresponding values of pure components + + state_1 :=setState_pTX( + state.p, + state.T, + {1,0}, + calcTransport=true); + if state.T < Tc[2]-1 then // + sat_2 := setSat_TX(state.T, {0,1}); + state_2 :=setState_pTX( + min(state.p,sat_2.psat-1), + state.T, + {0,1}, + calcTransport=true); + else + state_2 :=setState_pTX( + state.p, + state.T, + {0,1}, + calcTransport=true); + end if; + + lambda_1 :=Pure.lambda( + DM[1], + Vc[1], + Tc[1], + omega[1], + kappa[1], + MM[1], + state.T, + rho, + Cv[1], + beta[1]); + lambda_2 :=Pure.lambda( + DM[2], + Vc[2], + Tc[2], + omega[2], + kappa[2], + MM[2], + state.T, + rho, + Cv[2], + beta[2]); + + // Modelica.Utilities.Streams.print("got eta_1 = " + String(eta_1)); + // Modelica.Utilities.Streams.print("got state_1.eta = " + String(state_1.eta)); + // Modelica.Utilities.Streams.print("got eta_2 = " + String(eta_2)); + // Modelica.Utilities.Streams.print("got state_2.eta = " + String(state_2.eta)); + + lambda_1actual:=state_1.lambda; + lambda_2actual:=state_2.lambda; + + lambda := lambda + (state_1.lambda-lambda_1)*yi + (state_2.lambda-lambda_2)*yj; + + end thermalConductivity_VAPChungPureErrorWeight; + + partial function partialThermalConductivityLiquid + end partialThermalConductivityLiquid; + + function thermalConductivity_LIQLinearMoleElsayed "El-Sayed 1988" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := state.T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := state.T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + state_a := setState_TqX( + min(Tc_a - 1, Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w := setState_TqX( + min(Tcorr_w, Tc_w - 1), + 0, + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_LIQLinearMoleElsayed; + + function thermalConductivity_LIQConde "Conde 2006" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + Real rho_p1; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + Tcorr_a := state.T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := state.T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + state_a := setState_TqX( + min(Tc_a - 1, Tcorr_a), + 0, + {1,0}, + calcTransport=true); + state_w := setState_TqX( + min(Tcorr_w, Tc_w - 1), + 0, + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + // Modelica.Utilities.Streams.print("got first lambda = " + String(lambda_a)); + + rho_p1 := state_a.d*Z[1]^0.425; + state_a := setState_dqX( + max(rho_p1, 225), + 0, + {1,0}, + calcTransport=true); + + lambda_a := state_a.lambda; + + // Modelica.Utilities.Streams.print("got second lambda = " + String(lambda_a)); + + lambda := lambda_a*Z[1] + lambda_w*Z[2]; + + end thermalConductivity_LIQConde; + + function thermalConductivity_LIQFilipov "Filippov (in Poling 2001)" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Modelica.SIunits.Pressure pc_a=11333000; + constant Modelica.SIunits.Pressure pc_w=22064000; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + if state.T < Tc_a - 2 then + // + sat_a := setSat_TX(state.T, {1,0}); + state_a := setState_pTX( + max(state.p, sat_a.psat + 10), + state.T, + {1,0}, + calcTransport=true); + else + state_a := setState_pTX( + max(pc_a + 10, state.p), + Tc_a - 2, + {1,0}, + calcTransport=true); + end if; + + // the water will always be liquid + state_w := setState_pTX( + state.p, + min(state.T, Tc_w - 2), + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - 0.72*state.X[1]*state.X[ + 2]*max(lambda_a - lambda_w, lambda_w - lambda_a); + + end thermalConductivity_LIQFilipov; + + function thermalConductivity_LIQJamie "Jamieson (in Poling 2001)" + + extends partialThermalConductivityLiquid; + extends Modelica.Icons.Function; + input ThermodynamicState state "thermodynamic state record"; + output ThermalConductivity lambda; + + protected + ThermodynamicState state_w; + ThermodynamicState state_a; + SaturationProperties sat_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + constant Modelica.SIunits.Pressure pc_a=11333000; + constant Modelica.SIunits.Pressure pc_w=22064000; + + Modelica.SIunits.ThermalConductivity lambda_a; + Modelica.SIunits.ThermalConductivity lambda_w; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(state.X); + + if state.T < Tc_a - 2 then + // + sat_a := setSat_TX(state.T, {1,0}); + state_a := setState_pTX( + max(state.p, sat_a.psat + 10), + state.T, + {1,0}, + calcTransport=true); + else + state_a := setState_pTX( + max(pc_a + 10, state.p), + Tc_a - 2, + {1,0}, + calcTransport=true); + end if; + + // the water will always be liquid + state_w := setState_pTX( + state.p, + min(state.T, Tc_w - 2), + {0,1}, + calcTransport=true); + + lambda_a := state_a.lambda; + lambda_w := state_w.lambda; + + if lambda_a > lambda_w then + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - (lambda_a - + lambda_w)*(1 - sqrt(state.X[1]))*state.X[1]; + else + lambda := state.X[1]*lambda_a + state.X[2]*lambda_w - (lambda_w - + lambda_a)*(1 - sqrt(state.X[2]))*state.X[2]; + end if; + + end thermalConductivity_LIQJamie; + + function surfaceTensionTX + "Return surface tension, ideal solution based on corresponding temperature" + extends Modelica.Icons.Function; + input Temperature T; + input MassFraction X[nX] + "bulk mass fraction to determine critical T and p"; + output SurfaceTension sigma "Dynamic viscosity"; + + protected + SaturationProperties sat_w; + SaturationProperties sat_a; + + SurfaceTension sigma_w; + SurfaceTension sigma_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a = 405.560; + constant Modelica.SIunits.Temperature Tc_w = 647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + constant Modelica.SIunits.Temperature TNH3min=195.5; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(X); + + Tcorr_a := T*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := T*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String(Tcorr_w) + ")"); + end if; + + sat_a := setSat_TX( + max(TNH3min,Tcorr_a), + {1,0}, + calcTransport=true); + sat_w := setSat_TX( + Tcorr_w, + {0,1}, + calcTransport=true); + + sigma_a :=sat_a.sigma; + sigma_w :=sat_w.sigma; + + sigma:= sigma_a*Z[1] + sigma_w*Z[2]; + + end surfaceTensionTX; + + redeclare function surfaceTension + "Return surface tension, ideal solution based on corresponding temperature" + extends Modelica.Icons.Function; + input SaturationProperties sat; + output SurfaceTension sigma "Dynamic viscosity"; + + protected + SaturationProperties sat_w; + SaturationProperties sat_a; + + SurfaceTension sigma_w; + SurfaceTension sigma_a; + + Modelica.SIunits.Temperature Tc "critical temperature"; + Modelica.SIunits.Pressure pc "critical pressure"; + Modelica.SIunits.MoleFraction[nX] Z "mole fraction"; + + constant Modelica.SIunits.Temperature Tc_a=405.560; + constant Modelica.SIunits.Temperature Tc_w=647.096; + Modelica.SIunits.Temperature Tcorr_a "Corresponding temp. for ammonia, K"; + Modelica.SIunits.Temperature Tcorr_w "Corresponding temp. for water, K"; + + constant Modelica.SIunits.Temperature TNH3min=195.5; + + algorithm + (Tc,pc,Z) := criticalProperties_sassen1990(sat.X); + + Tcorr_a := sat.Tsat*Tc_a/Tc "Corresponding temp. for ammonia, K"; + Tcorr_w := sat.Tsat*Tc_w/Tc "Corresponding temp. for water, K"; + + if debugmode then + Modelica.Utilities.Streams.print("got (Tc,pc,Tcorr_a,Tcorr_w), (" + + String(Tc) + "," + String(pc) + "," + String(Tcorr_a) + "," + String( + Tcorr_w) + ")"); + end if; + + sat_a := setSat_TX( + min(Tc_a - 1, max(TNH3min, Tcorr_a)), + {1,0}, + calcTransport=true); + sat_w := setSat_TX( + min(Tcorr_w, Tc_w - 1), + {0,1}, + calcTransport=true); + + sigma_a := sat_a.sigma; + sigma_w := sat_w.sigma; + + sigma := sigma_a*Z[1] + sigma_w*Z[2]; + + end surfaceTension; + + + end NH3_Water; From a27f27bd8929f2ccb3d4c53d85b3aa9838e76308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Mon, 16 Jun 2014 14:03:36 +0200 Subject: [PATCH 56/57] Made package inside testers specifically to test ammonia-water mixture 1. partial derivative, 2. transport properties --- Media/Pentane.mo | 5 - Media/R410mix.mo | 5 - Media/Water.mo | 5 - Testers/AmmoniaWater.mo | 1313 +++++++++++++++++ Testers/NH3Water_MUXvsPHXvsPTX.mo | 545 ------- Testers/NH3_Water_setSatModel.mo | 25 - Testers/NH3_Water_setStateModel.mo | 42 - ...Water_setStateModel_test_partial_inputs.mo | 32 - Testers/PropsMixtureNH3H2O.mo | 41 - .../Water_MixtureTwoPhase_pT/package.bak-mo | 22 - Testers/package.mo | 6 + Testers/package.order | 5 +- 12 files changed, 1320 insertions(+), 726 deletions(-) delete mode 100644 Media/Pentane.mo delete mode 100644 Media/R410mix.mo delete mode 100644 Media/Water.mo create mode 100644 Testers/AmmoniaWater.mo delete mode 100644 Testers/NH3Water_MUXvsPHXvsPTX.mo delete mode 100644 Testers/NH3_Water_setSatModel.mo delete mode 100644 Testers/NH3_Water_setStateModel.mo delete mode 100644 Testers/NH3_Water_setStateModel_test_partial_inputs.mo delete mode 100644 Testers/PropsMixtureNH3H2O.mo delete mode 100644 Testers/Water_MixtureTwoPhase_pT/package.bak-mo diff --git a/Media/Pentane.mo b/Media/Pentane.mo deleted file mode 100644 index 22d21a6..0000000 --- a/Media/Pentane.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Pentane "Pentane from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"pentane"}); -end Pentane; diff --git a/Media/R410mix.mo b/Media/R410mix.mo deleted file mode 100644 index 1d03112..0000000 --- a/Media/R410mix.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package R410mix "R410 defined as mixture in REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"R32","R125"},reference_X={0.697615,0.302385}); -end R410mix; diff --git a/Media/Water.mo b/Media/Water.mo deleted file mode 100644 index 67db3b5..0000000 --- a/Media/Water.mo +++ /dev/null @@ -1,5 +0,0 @@ -within REFPROP2Modelica.Media; -package Water "Water from REFPROP library" - extends Interfaces.REFPROPMixtureTwoPhaseMedium( - final substanceNames={"water"}); -end Water; diff --git a/Testers/AmmoniaWater.mo b/Testers/AmmoniaWater.mo new file mode 100644 index 0000000..1a523d2 --- /dev/null +++ b/Testers/AmmoniaWater.mo @@ -0,0 +1,1313 @@ +within REFPROP2Modelica.Testers; +package AmmoniaWater + + model NH3_Water_setSatModel + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState dewstate; + Medium.ThermodynamicState bubstate; + + Medium.SaturationProperties satL; + Medium.SaturationProperties satL2; + Medium.SaturationProperties satV; + + Medium.AbsolutePressure p; + Medium.MassFraction X[2]; + + Real A[3]; + Real B[2]; + + Real sigma; + equation + (A[1],A[2],A[3],B) = Medium.criticalProperties(X); + + p=100e5; + X={0.5,0.5}; + + satL = Medium.setSat_pX(p,X,kph=1,calcTransport=false); + satL2 = Medium.setSat_TX(satL.Tsat,X,kph=1,calcTransport=false); + bubstate = Medium.setBubbleState(satL); + + satV = Medium.setSat_pX(p,X,kph=2,calcTransport=false); + dewstate = Medium.setDewState(satV); + + sigma = Medium.surfaceTension(satL); + + end NH3_Water_setSatModel; + + model NH3_Water_setStateModel + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState state; + // Medium.SaturationProperties sat; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + Medium.Density d; + + Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; + + Real q; + + Real dddh_pX; + Real dddp_hX; + Real dddh_pX_num; + Real dddp_hX_num; + + //Real dddX_ph_num; + + equation + p=100e5; + h=3e5 + time*25e5; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); + q = Medium.vapourQuality(state); + d = Medium.density(state); + + dddh_pX = Medium.density_derh_p(state); + dddh_pX_num = Medium.density(Medium.setState_phX(p,h+1,X))-d; + + dddp_hX = Medium.density_derp_h(state); + dddp_hX_num = Medium.density(Medium.setState_phX(p+1,h,X))-d; + + // dddX_ph_num = (Medium.density(Medium.setState_phX(p,h,cat(1,{X[1]+0.0001},{X[2]-0.0001})))-d)/0.0001; + + end NH3_Water_setStateModel; + + model NH3_Water_setState_plus_setSat + + package Medium = REFPROP2Modelica.Media.NH3_Water; + + Medium.ThermodynamicState state; + Medium.SaturationProperties sat; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + + Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; + + //Real dddX_ph_num; + + Medium.ThermodynamicState dewstate; + Medium.ThermodynamicState bubstate; + + equation + p=150e5; + h=3e5 + time*25e5; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); + + sat = state.sat; + + bubstate = Medium.setBubbleState(sat); + dewstate = Medium.setDewState(sat); + + // sat = if state.q<=0 then Medium.setSat_pX(p,X,kph=1) elseif state.q>=1 then Medium.setSat_pX(p,X,kph=2) else state.sat; + + end NH3_Water_setState_plus_setSat; + + model NH3_Water_setStateModel_test_partial_inputs + + package Medium = REFPROP2Modelica.Media.NH3_Water; + //package Medium2 = REFPROP2Modelica.Media.NH3_Water; + + // Medium.PartialDersInputChoice partialDersInputChoice = Medium.PartialDersInputChoice.none; + // Medium2.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.pTX_numeric; + + Medium.ThermodynamicState state; + Medium.ThermodynamicState state2; + + // input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[2]; + + parameter Medium.PartialDersInputChoice partialDersInputChoice0 = Medium.PartialDersInputChoice.none; + parameter Medium.PartialDersInputChoice partialDersInputChoice1 = Medium.PartialDersInputChoice.phX_numeric; + parameter Medium.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.phX_pseudoanalytic; + parameter Medium.PartialDersInputChoice partialDersInputChoice3 = Medium.PartialDersInputChoice.pTX_numeric; + + equation + p=50e5; + h=3e5+time*100e3; + X={0.5,0.5}; + + state = Medium.setState_phX(p,h,X); + state2 = Medium.setState_phX(p,h,X,partialDersInputChoice=3); + + end NH3_Water_setStateModel_test_partial_inputs; + + package NH3Water_MUXvsPHXvsPTX + + model Volume_MUX "NH3 Water" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start = Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u(start = hstart-pstart/Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + // Real X1(start=X1start); + + Medium.AbsolutePressure p; + Medium.SpecificEnthalpy h; + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=400); + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // Mass conservation + V * der(d) = port.m_flow; + // species conservation + V * (X[1]*der(d) + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(u) + u*der(d)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // Thermodynamic properties + state = Medium.setState_dTX(d,T,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + //T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_MUX; + + model Volume_phX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d; + Medium.SpecificInternalEnergy u; + // Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T; + + Real dddt; + // Real dhdt; + // Real dddX[Medium.nX]; + // Real dddX_num; + // Real dddX_num_check; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // derivative transformations + dddt = Medium.density_derh_p(state)*der(h) + Medium.density_derp_h(state)*der(p) + state.dddX_ph*der(X[1]); + // dddX = Medium.density_derX(state); + // dhdt = Medium.h_TX_der(T=T,X=X,dT=der(T),dX={der(X[1]),-der(X[1])}) "h is function of T and X only... and not p"; + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*der(h) + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // der(u)=0; + // der(d)=0; + // der(X1)=0; + + // // Thermodynamic properties + // state = Medium.setState_phX(p,h,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + // T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + // p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_phX(p,h,X,partialDersInputChoice=3); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + d = Medium.density(state); + // p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + // additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + + // dddX_num = (Medium.density(state_dX)-d)/0.0001; + // dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_phX; + + model Volume_pTX "ideal gas mixture" + + replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby + REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); + Medium.ThermodynamicState state; + + parameter Modelica.SIunits.Volume V=1; + + parameter Real hstart=3500e3; + parameter Real pstart=50e5; + parameter Real X1start=0.5; + + Medium.Density d(start=Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + Medium.SpecificInternalEnergy u; + // Real X1(start=X1start); + + Medium.AbsolutePressure p(start=pstart); + Medium.SpecificEnthalpy h(start=hstart); + Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); + Medium.Temperature T(start=Medium.temperature(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); + + Real dddt; + Real dhdt; + + Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) + annotation (Placement(transformation(extent={{50,-10},{70,10}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" + annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), + iconTransformation(extent={{-20,50},{20,70}}))); + + equation + // derivative transformations + dddt = state.dddT_pX*der(T) + state.dddp_TX*der(p) + state.dddX_pT*der(X[1]); + dhdt = state.dhdT_pX*der(T) + state.dhdp_TX*der(p) + state.dhdX_pT*der(X[1]); + + // Mass conservation + V * dddt = port.m_flow; + // species conservation + V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); + X[2] = 1-X[1]; + // energy cons + V * (d*dhdt + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; + + // der(u)=0; + // der(d)=0; + // der(X1)=0; + + // // Thermodynamic properties + // state = Medium.setState_phX(p,h,X); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + // T = Medium.temperature(state); + // h = Medium.specificEnthalpy(state); + // d = Medium.density(state); + // p = Medium.pressure(state); + + // Thermodynamic properties + state = Medium.setState_pTX(p,T,X,partialDersInputChoice=4); + // sat = Medium.setSat_pX(p,X[:]); + // u = Medium.specificInternalEnergy(state); + u = h - p/d; + // T = Medium.temperature(state); + h = Medium.specificEnthalpy(state); + d = Medium.density(state); + // p = Medium.pressure(state); + + // port connections + h = port.h_outflow; + X[1] = port.Xi_outflow[1]; + // X[2] = port.Xi_outflow[2]; + p = port.p; + T = heatPort.T; + + // additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... + + // dddX_num = (Medium.density(state_dX)-d)/0.0001; + // dddX_num_check = dddX[1] - dddX[2]; + + annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), + graphics={Ellipse( + extent={{-60,60},{60,-60}}, + lineColor={0,0,255}, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid)})); + end Volume_pTX; + + model system_MUX_sp + + Volume_MUX volume(V=0.01, hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); + equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); + end system_MUX_sp; + + model system_MUX_tp + + Volume_MUX volume(V=0.01, hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); + Modelica.Fluid.Sources.MassFlowSource_h boundary( + nPorts=1, + use_h_in=false, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); + equation + connect(boundary.ports[1], volume.port) annotation (Line( + points={{58,34},{66,34},{66,0},{-16,0}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( + points={{-26,40},{-24,40},{-24,6},{-22,6}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics)); + end system_MUX_tp; + + model system_phX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + V=0.01, + hstart=3000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_phX_sp; + + model system_phX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + m_flow=0, + use_m_flow_in=true, + X={0.8,0.2}, + h=2000e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + V=0.01, + hstart=1500e3, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(sine.y, boundary.m_flow_in) annotation (Line( + points={{24.6,36},{30,36},{30,42},{38,42}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_phX_tp; + + model system_pTX_sp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=3000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=3000e3) + annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-26,8},{-18,8},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_pTX_sp; + + model system_pTX_tp + + Modelica.Fluid.Sources.MassFlowSource_h boundary( + use_h_in=false, + nPorts=1, + redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, + m_flow=0, + X={0.8,0.2}, + use_m_flow_in=true, + h=2000e3) + annotation (Placement(transformation(extent={{38,24},{58,44}}))); + Modelica.Blocks.Sources.Sine sine( + freqHz=5, + amplitude=0.1, + offset=0.2, + startTime=0) + annotation (Placement(transformation(extent={{12,30},{24,42}}))); + Volume_pTX volume(V=0.01, hstart=1500e3) + annotation (Placement(transformation(extent={{-38,-10},{-16,12}}))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow + annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); + Modelica.Blocks.Sources.Sine sine1( + freqHz=1, + amplitude=-5000000, + offset=0, + startTime=100) + annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); + equation + connect(volume.port, boundary.ports[1]) annotation (Line( + points={{-20.4,1},{32,1},{32,0},{78,0},{78,34},{58,34}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( + points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( + points={{-27,7.6},{-18,7.6},{-18,38},{-20,38}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boundary.m_flow_in, sine.y) annotation (Line( + points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ + {-100,-100},{100,100}}))); + end system_pTX_tp; + + end NH3Water_MUXvsPHXvsPTX; + +package TransportPropsTest + model MassFractionSweep_visc_vap + + parameter Modelica.SIunits.Pressure p=100e5; + parameter Modelica.SIunits.Temperature T=325 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package MediumWilke = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPWilke); + MediumWilke.ThermodynamicState state=MediumWilke.setState_pTX( + p, + T, + X, + calcTransport=false); + + package MediumReich = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPReichenberg); + + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChung); + + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight); + + //Real eta_reich,eta_chung,eta_chungErrorWeight; + Real eta_wilke; + Real eta_reich; + Real eta_chung; + Real eta_chungErrorWeight; + + equation + X = {time,1 - time}; + + eta_wilke = MediumWilke.dynamicViscosity(state); + eta_reich = MediumReich.dynamicViscosity(state); + eta_chung = MediumChung.dynamicViscosity(state); + eta_chungErrorWeight = MediumChungErrorWeight.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_visc_vap; + + model EnthalpySweep_visc_vap + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Medium.AbsolutePressure p=150e5; + // parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.Temperature Tend=500+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pqX(p,1,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pTX(p,Tend,X)); + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + Real h; + Real eta_chung,eta_chungWeight,eta_wilke,eta_reichenberg; + + package MediumWilke = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPWilke); + + package MediumReich = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPReichenberg); + + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChung); + + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityVapor = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight); + equation + h=hstart + (hend-hstart)*time; + + eta_chung = Medium.dynamicViscosity_VAPChung(state); + eta_chungWeight = Medium.dynamicViscosity_VAPChungPureErrorWeight(state); + eta_wilke = Medium.dynamicViscosity_VAPWilke(state); + eta_reichenberg = Medium.dynamicViscosity_VAPReichenberg(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_visc_vap; + + model MassFractionSweep_visc_liq + + parameter Modelica.SIunits.Pressure p=50e5; + parameter Modelica.SIunits.Temperature T=50 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state=Medium.setState_pTX( + p, + T, + X, + calcTransport=false); + + Real eta_conde,eta_elsayed,eta_HDK,eta_TejaRice,eta_TejaRiceStecco,eta_TejaRiceSassensTcrit; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQconde); + + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQelsayed); + + package MediumHdbKaltetechnik = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQHDK); + + package MediumSteccoDesideri = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay); + + package MediumTejaRice = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRice); + + package MediumTejaRiceSassen = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSassensTcrit); + + equation + X = {time,1 - time}; + + eta_conde = MediumConde.dynamicViscosity(state); + eta_elsayed = MediumElSayed.dynamicViscosity(state); + eta_HDK = MediumHdbKaltetechnik.dynamicViscosity(state); + eta_TejaRiceStecco = MediumSteccoDesideri.dynamicViscosity(state); + eta_TejaRice = MediumTejaRice.dynamicViscosity(state); + eta_TejaRiceSassensTcrit = MediumTejaRiceSassen.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_visc_liq; + + model EnthalpySweep_visc_liq + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + parameter Medium.AbsolutePressure p=100e5; + parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + Real h; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pTX(p,Tstart,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pqX(p,0,X)); + Real eta_conde,eta_elsayed,eta_HDK,eta_TejaRiceStecco; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQconde); + + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQelsayed); + + package MediumHdbKaltetechnik = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQHDK); + + package MediumSteccoDesideri = REFPROP2Modelica.Media.NH3_Water ( + redeclare function DynamicViscosityLiquid = + REFPROP2Modelica.Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay); + + equation + h=hstart + (hend-hstart)*time; + + eta_conde = MediumConde.dynamicViscosity(state); + eta_elsayed = MediumElSayed.dynamicViscosity(state); + eta_HDK = MediumHdbKaltetechnik.dynamicViscosity(state); + eta_TejaRiceStecco = MediumSteccoDesideri.dynamicViscosity(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_visc_liq; + + model MassFractionSweep_cond_vap + + parameter Modelica.SIunits.Pressure p=100e5; + parameter Modelica.SIunits.Temperature T=325 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package MediumAverage = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPLinearMolePoling); + MediumAverage.ThermodynamicState state=MediumAverage.setState_pTX( + p, + T, + X, + calcTransport=false); + + package MediumMasonSaxena = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPWilke); + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChung); + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight); + + Real lambda_wilke,lambda_polingLin,lambda_chung,lambda_chungErrorWeight; + + equation + X = {time,1 - time}; + + lambda_wilke = MediumAverage.thermalConductivity(state); + lambda_polingLin = MediumMasonSaxena.thermalConductivity(state); + lambda_chung = MediumChung.thermalConductivity(state); + lambda_chungErrorWeight = MediumChungErrorWeight.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_cond_vap; + + model EnthalpySweep_cond_vap + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Medium.AbsolutePressure p=150e5; + // parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.Temperature Tend=500 + 273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + parameter Real hstart=Medium.specificEnthalpy(Medium.setState_pqX( + p, + 1, + X)); + parameter Real hend=Medium.specificEnthalpy(Medium.setState_pTX( + p, + Tend, + X)); + Medium.ThermodynamicState state=Medium.setState_phX( + p, + h, + X); + + Real h; + Real lambda_wilke; + Real lambda_chung; + Real lambda_chungErrorWeight; + Real lambda_polingLin; + + package MediumAverage = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPLinearMolePoling); + package MediumMasonSaxena = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPWilke); + package MediumChung = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChung); + package MediumChungErrorWeight = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityVapor = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight); + + equation + h = hstart + (hend - hstart)*time; + + lambda_wilke = MediumAverage.thermalConductivity(state); + lambda_polingLin = MediumMasonSaxena.thermalConductivity(state); + lambda_chung = MediumChung.thermalConductivity(state); + lambda_chungErrorWeight = MediumChungErrorWeight.thermalConductivity( + state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_cond_vap; + + model MassFractionSweep_cond_liq + + parameter Modelica.SIunits.Pressure p=50e5; + parameter Modelica.SIunits.Temperature T=50 + 273.15; + Modelica.SIunits.MassFraction X[2]; + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_pTX(p,T,X,calcTransport=false); + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQConde); + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed); + package MediumFilippov = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQFilipov); + package MediumJamieson = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQJamie); + + Real lambda_elsayed,lambda_conde,lambda_filipov,lambda_jamieson; + + equation + X={time,1-time}; + + lambda_conde = MediumConde.thermalConductivity(state); + lambda_elsayed = MediumElSayed.thermalConductivity(state); + lambda_filipov = MediumFilippov.thermalConductivity(state); + lambda_jamieson = MediumJamieson.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end MassFractionSweep_cond_liq; + + model EnthalpySweep_cond_liq + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.ThermodynamicState state = Medium.setState_phX(p,h,X); + + parameter Medium.AbsolutePressure p=100e5; + parameter Medium.Temperature Tstart=50+273.15; + parameter Medium.MassFraction X[2]={0.5,0.5}; + Real h; + parameter Real hstart = Medium.specificEnthalpy(Medium.setState_pTX(p,Tstart,X)); + parameter Real hend = Medium.specificEnthalpy(Medium.setState_pqX(p,0,X)); + + Real lambda_elsayed,lambda_conde,lambda_filipov,lambda_jamieson; + + package MediumConde = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQConde); + package MediumElSayed = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed); + package MediumFilippov = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQFilipov); + package MediumJamieson = REFPROP2Modelica.Media.NH3_Water ( + redeclare function ThermalConductivityLiquid = + REFPROP2Modelica.Media.NH3_Water.thermalConductivity_LIQJamie); + + equation + h=hstart + (hend-hstart)*time; + // h=hstart + (2e6-hstart)*time; + + lambda_conde = MediumConde.thermalConductivity(state); + lambda_elsayed = MediumElSayed.thermalConductivity(state); + lambda_filipov = MediumFilippov.thermalConductivity(state); + lambda_jamieson = MediumJamieson.thermalConductivity(state); + + annotation (experiment(Interval=0.01)); + end EnthalpySweep_cond_liq; + + model MassFractionSweepSurfaceTension + + package Medium = REFPROP2Modelica.Media.NH3_Water; + Medium.SaturationProperties sat; + Real T; + Medium.MassFraction X[2]; + Real sigma; + + equation + X={time,1-time}; + sat = Medium.setSat_TX(T,X,calcTransport=true); + T=350+273.15; + + sigma = Medium.surfaceTension(sat); + + end MassFractionSweepSurfaceTension; + +package TestCore + model liquid_viscosity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state50[n] annotation(hideResult=true); + Medium.ThermodynamicState state90[n] annotation(hideResult=true); + Medium.ThermodynamicState state130[n] annotation(hideResult=true); + Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real eta_conde50[n]; + Real eta_elsayed50[n]; + Real eta_HDK50[n]; + Real eta_TejaRice50[n]; + Real eta_TejaRiceStecco50[n]; + + Real eta_conde90[n]; + Real eta_elsayed90[n]; + Real eta_HDK90[n]; + Real eta_TejaRice90[n]; + Real eta_TejaRiceStecco90[n]; + + Real eta_conde130[n]; + Real eta_elsayed130[n]; + Real eta_HDK130[n]; + Real eta_TejaRice130[n]; + Real eta_TejaRiceStecco130[n]; + + equation + p=50e5; + + for i in 1:n loop + state50[i] = Medium.setState_pTX(p,50+273.15,{x1[i],1-x1[i]}); + eta_conde50[i] = Media.NH3_Water.dynamicViscosity_LIQconde( state50[i]); + eta_elsayed50[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed( state50[i]); + eta_HDK50[i] = Media.NH3_Water.dynamicViscosity_LIQHDK( state50[i]); + eta_TejaRice50[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state50[i]); + eta_TejaRiceStecco50[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state50[i]); + + state90[i] = Medium.setState_pTX(p,90+273.15,{x1[i],1-x1[i]}); + eta_conde90[i] = Media.NH3_Water.dynamicViscosity_LIQconde( state90[i]); + eta_elsayed90[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed( state90[i]); + eta_HDK90[i] = Media.NH3_Water.dynamicViscosity_LIQHDK( state90[i]); + eta_TejaRice90[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state90[i]); + eta_TejaRiceStecco90[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state90[i]); + + state130[i] = Medium.setState_pTX(p,130+273.15,{x1[i],1-x1[i]}); + eta_conde130[i] = Media.NH3_Water.dynamicViscosity_LIQconde(state130[i]); + eta_elsayed130[i] = Media.NH3_Water.dynamicViscosity_LIQelsayed(state130[i]); + eta_HDK130[i] = Media.NH3_Water.dynamicViscosity_LIQHDK(state130[i]); + eta_TejaRice130[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRice(state130[i]); + eta_TejaRiceStecco130[i] = Media.NH3_Water.dynamicViscosity_LIQTejeRiceSteccoWay(state130[i]); + + end for; + + end liquid_viscosity_sweep; + + model vapor_viscosity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state_325_050[n] annotation(hideResult=true); + Medium.ThermodynamicState state_325_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_525_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_425_100[n] annotation(hideResult=true); + // Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real eta_reich_325_050[n]; + Real eta_reich_325_100[n]; + Real eta_reich_525_100[n]; + Real eta_reich_425_100[n]; + + Real eta_wilke_325_050[n]; + Real eta_wilke_325_100[n]; + Real eta_wilke_525_100[n]; + Real eta_wilke_425_100[n]; + + Real eta_chung_325_050[n]; + Real eta_chung_325_100[n]; + Real eta_chung_525_100[n]; + Real eta_chung_425_100[n]; + + Real eta_chungWeight_325_050[n]; + Real eta_chungWeight_325_100[n]; + Real eta_chungWeight_525_100[n]; + Real eta_chungWeight_425_100[n]; + equation + for i in 1:n loop + + // state_315_100[i] = Medium.setState_pTX(100e5,315+273.15,{x1[i],1-x1[i]}); + // eta_reich_315_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_315_100[i]); + // eta_wilke_315_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_315_100[i]); + // + // state_330_125[i] = Medium.setState_pTX(125e5,330+273.15,{x1[i],1-x1[i]}); + // eta_reich_330_125[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_330_125[i]); + // eta_wilke_330_125[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_330_125[i]); + // + // state_345_150[i] = Medium.setState_pTX(150e5,345+273.15,{x1[i],1-x1[i]}); + // eta_reich_345_150[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_345_150[i]); + // eta_wilke_345_150[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_345_150[i]); + + // state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + // eta_reich_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_050[i]); + // eta_wilke_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_050[i]); + // eta_chung_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_050[i]); + // + // state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + // eta_reich_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_100[i]); + // eta_wilke_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_100[i]); + // eta_chung_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_100[i]); + // + // state_375_100[i] = Medium.setState_pTX(100e5,375+273.15,{x1[i],1-x1[i]}); + // eta_reich_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_375_100[i]); + // eta_wilke_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_375_100[i]); + // eta_chung_375_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_375_100[i]); + // + // state_425_100[i] = Medium.setState_pTX(100e5,425+273.15,{x1[i],1-x1[i]}); + // eta_reich_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_425_100[i]); + // eta_wilke_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_425_100[i]); + // eta_chung_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_425_100[i]); + + state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + eta_reich_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_050[i]); + eta_wilke_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_050[i]); + eta_chung_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_050[i]); + eta_chungWeight_325_050[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_325_050[i]); + + state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + eta_reich_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_325_100[i]); + eta_wilke_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_325_100[i]); + eta_chung_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_325_100[i]); + eta_chungWeight_325_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_325_100[i]); + + state_425_100[i] = Medium.setState_pTX(100e5,425+273.15,{x1[i],1-x1[i]}); + eta_reich_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_425_100[i]); + eta_wilke_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_425_100[i]); + eta_chung_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_425_100[i]); + eta_chungWeight_425_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_425_100[i]); + + state_525_100[i] = Medium.setState_pTX(100e5,525+273.15,{x1[i],1-x1[i]}); + eta_reich_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPReichenberg( state_525_100[i]); + eta_wilke_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPWilke( state_525_100[i]); + eta_chung_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPChung( state_525_100[i]); + eta_chungWeight_525_100[i] = Media.NH3_Water.dynamicViscosity_VAPChungPureErrorWeight( state_525_100[i]); + + end for; + + end vapor_viscosity_sweep; + + model liquid_conductivity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + + Medium.ThermodynamicState state50_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state90_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state130_100[n] annotation(hideResult=true); + + Real x1[n] = linspace(0,1,n); + + Real lambda_elsayedLin50_100[n]; + Real lambda_filipov50_100[n]; + Real lambda_jamieson50_100[n]; + Real lambda_conde50_100[n]; + + Real lambda_elsayedLin90_100[n]; + Real lambda_filipov90_100[n]; + Real lambda_jamieson90_100[n]; + Real lambda_conde90_100[n]; + + Real lambda_elsayedLin130_100[n]; + Real lambda_filipov130_100[n]; + Real lambda_jamieson130_100[n]; + Real lambda_conde130_100[n]; + + equation + for i in 1:n loop + state50_100[i] = Medium.setState_pTX(100e5,50+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin50_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state50_100[i]); + lambda_filipov50_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state50_100[i]); + lambda_jamieson50_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state50_100[i]); + lambda_conde50_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state50_100[i]); + + state90_100[i] = Medium.setState_pTX(100e5,90+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin90_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state90_100[i]); + lambda_filipov90_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state90_100[i]); + lambda_jamieson90_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state90_100[i]); + lambda_conde90_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state90_100[i]); + + state130_100[i] = Medium.setState_pTX(100e5,130+273.15,{x1[i],1-x1[i]}); + lambda_elsayedLin130_100[i] = Media.NH3_Water.thermalConductivity_LIQLinearMoleElsayed( state130_100[i]); + lambda_filipov130_100[i] = Media.NH3_Water.thermalConductivity_LIQFilipov( state130_100[i]); + lambda_jamieson130_100[i] = Media.NH3_Water.thermalConductivity_LIQJamie( state130_100[i]); + lambda_conde130_100[i] = Media.NH3_Water.thermalConductivity_LIQConde( state130_100[i]); + + end for; + + end liquid_conductivity_sweep; + + model vapor_conductivity_sweep + + package Medium = REFPROP2Modelica.Media.NH3_Water; + parameter Integer n=101; + Medium.ThermodynamicState state_325_050[n] annotation(hideResult=true); + Medium.ThermodynamicState state_325_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_425_100[n] annotation(hideResult=true); + Medium.ThermodynamicState state_525_100[n] annotation(hideResult=true); + // Medium.AbsolutePressure p; + + Real x1[n] = linspace(0,1,n); + + Real lambda_polingLin_325_050[n]; + Real lambda_polingLin_325_100[n]; + Real lambda_polingLin_425_100[n]; + Real lambda_polingLin_525_100[n]; + + Real lambda_wilke_325_050[n]; + Real lambda_wilke_325_100[n]; + Real lambda_wilke_425_100[n]; + Real lambda_wilke_525_100[n]; + + Real lambda_chung_325_050[n]; + Real lambda_chung_325_100[n]; + Real lambda_chung_425_100[n]; + Real lambda_chung_525_100[n]; + + Real lambda_chungErrorWeight_325_050[n]; + Real lambda_chungErrorWeight_325_100[n]; + Real lambda_chungErrorWeight_425_100[n]; + Real lambda_chungErrorWeight_525_100[n]; + + equation + for i in 1:n loop + + state_325_050[i] = Medium.setState_pTX(050e5,325+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_325_050[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_325_050[i]); + lambda_wilke_325_050[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_325_050[i]); + lambda_chung_325_050[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_325_050[i]); + lambda_chungErrorWeight_325_050[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_325_050[i]); + + state_325_100[i] = Medium.setState_pTX(100e5,325+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_325_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_325_100[i]); + lambda_wilke_325_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_325_100[i]); + lambda_chung_325_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_325_100[i]); + lambda_chungErrorWeight_325_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_325_100[i]); + + state_425_100[i] = Medium.setState_pTX(100e5,475+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_425_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_425_100[i]); + lambda_wilke_425_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_425_100[i]); + lambda_chung_425_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_425_100[i]); + lambda_chungErrorWeight_425_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_425_100[i]); + + state_525_100[i] = Medium.setState_pTX(100e5,525+273.15,{x1[i],1-x1[i]}); + lambda_polingLin_525_100[i] = Media.NH3_Water.thermalConductivity_VAPLinearMolePoling( state_525_100[i]); + lambda_wilke_525_100[i] = Media.NH3_Water.thermalConductivity_VAPWilke( state_525_100[i]); + lambda_chung_525_100[i] = Media.NH3_Water.thermalConductivity_VAPChung(state_525_100[i]); + lambda_chungErrorWeight_525_100[i] = Media.NH3_Water.thermalConductivity_VAPChungPureErrorWeight(state_525_100[i]); + + end for; + + end vapor_conductivity_sweep; +end TestCore; +end TransportPropsTest; +end AmmoniaWater; diff --git a/Testers/NH3Water_MUXvsPHXvsPTX.mo b/Testers/NH3Water_MUXvsPHXvsPTX.mo deleted file mode 100644 index e009705..0000000 --- a/Testers/NH3Water_MUXvsPHXvsPTX.mo +++ /dev/null @@ -1,545 +0,0 @@ -within REFPROP2Modelica.Testers; -package NH3Water_MUXvsPHXvsPTX - -model Volume_MUX "NH3 Water" - - replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby - REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); - Medium.ThermodynamicState state; - - parameter Modelica.SIunits.Volume V=1; - - parameter Real hstart=3500e3; - parameter Real pstart=50e5; - parameter Real X1start=0.5; - - Medium.Density d(start = Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); - Medium.SpecificInternalEnergy u(start = hstart-pstart/Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); -// Real X1(start=X1start); - - Medium.AbsolutePressure p; - Medium.SpecificEnthalpy h; - Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); - Medium.Temperature T(start=400); - - Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) - annotation (Placement(transformation(extent={{50,-10},{70,10}}))); - -Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" - annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), - iconTransformation(extent={{-20,50},{20,70}}))); - -equation - // Mass conservation - V * der(d) = port.m_flow; - // species conservation - V * (X[1]*der(d) + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); - X[2] = 1-X[1]; - // energy cons - V * (d*der(u) + u*der(d)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; - - // Thermodynamic properties - state = Medium.setState_dTX(d,T,X); -// sat = Medium.setSat_pX(p,X[:]); -// u = Medium.specificInternalEnergy(state); -u = h - p/d; -//T = Medium.temperature(state); - h = Medium.specificEnthalpy(state); -// d = Medium.density(state); - p = Medium.pressure(state); - -// port connections - h = port.h_outflow; - X[1] = port.Xi_outflow[1]; -// X[2] = port.Xi_outflow[2]; - p = port.p; - T = heatPort.T; - - annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, - extent={{-100,-100},{100,100}}), - graphics={Ellipse( - extent={{-60,60},{60,-60}}, - lineColor={0,0,255}, - fillColor={0,0,255}, - fillPattern=FillPattern.Solid)})); -end Volume_MUX; - -model Volume_phX "ideal gas mixture" - - replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby - REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); - Medium.ThermodynamicState state; - - parameter Modelica.SIunits.Volume V=1; - - parameter Real hstart=3500e3; - parameter Real pstart=50e5; - parameter Real X1start=0.5; - - Medium.Density d; - Medium.SpecificInternalEnergy u; -// Real X1(start=X1start); - - Medium.AbsolutePressure p(start=pstart); - Medium.SpecificEnthalpy h(start=hstart); - Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); - Medium.Temperature T; - - Real dddt; -// Real dhdt; -// Real dddX[Medium.nX]; -// Real dddX_num; -// Real dddX_num_check; - - Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) - annotation (Placement(transformation(extent={{50,-10},{70,10}}))); - -Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" - annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), - iconTransformation(extent={{-20,50},{20,70}}))); - -equation - // derivative transformations - dddt = Medium.density_derh_p(state)*der(h) + Medium.density_derp_h(state)*der(p) + state.dddX_ph*der(X[1]); - // dddX = Medium.density_derX(state); - // dhdt = Medium.h_TX_der(T=T,X=X,dT=der(T),dX={der(X[1]),-der(X[1])}) "h is function of T and X only... and not p"; - - // Mass conservation - V * dddt = port.m_flow; - // species conservation - V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); - X[2] = 1-X[1]; - // energy cons - V * (d*der(h) + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; - -// der(u)=0; -// der(d)=0; -// der(X1)=0; - -// // Thermodynamic properties -// state = Medium.setState_phX(p,h,X); -// sat = Medium.setSat_pX(p,X[:]); -// u = Medium.specificInternalEnergy(state); -// T = Medium.temperature(state); -// h = Medium.specificEnthalpy(state); -// d = Medium.density(state); -// p = Medium.pressure(state); - - // Thermodynamic properties - state = Medium.setState_phX(p,h,X,partialDersInputChoice=3); -// sat = Medium.setSat_pX(p,X[:]); -// u = Medium.specificInternalEnergy(state); -u = h - p/d; - T = Medium.temperature(state); -// h = Medium.specificEnthalpy(state); - d = Medium.density(state); -// p = Medium.pressure(state); - -// port connections - h = port.h_outflow; - X[1] = port.Xi_outflow[1]; -// X[2] = port.Xi_outflow[2]; - p = port.p; - T = heatPort.T; - -// additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... - -// dddX_num = (Medium.density(state_dX)-d)/0.0001; -// dddX_num_check = dddX[1] - dddX[2]; - - annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, - extent={{-100,-100},{100,100}}), - graphics={Ellipse( - extent={{-60,60},{60,-60}}, - lineColor={0,0,255}, - fillColor={0,0,255}, - fillPattern=FillPattern.Solid)})); -end Volume_phX; - -model Volume_pTX "ideal gas mixture" - - replaceable package Medium = REFPROP2Modelica.Media.NH3_Water constrainedby - REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium annotation (choicesAllMatching=true); - Medium.ThermodynamicState state; - - parameter Modelica.SIunits.Volume V=1; - - parameter Real hstart=3500e3; - parameter Real pstart=50e5; - parameter Real X1start=0.5; - - Medium.Density d(start=Medium.density(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); - Medium.SpecificInternalEnergy u; -// Real X1(start=X1start); - - Medium.AbsolutePressure p(start=pstart); - Medium.SpecificEnthalpy h(start=hstart); - Medium.MassFraction X[Medium.nX](start={X1start,1-X1start}); - Medium.Temperature T(start=Medium.temperature(Medium.setState_phX(pstart,hstart,{X1start,1-X1start}))); - - Real dddt; - Real dhdt; - - Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium=Medium) - annotation (Placement(transformation(extent={{50,-10},{70,10}}))); - -Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Thermal port" - annotation (Placement(transformation(extent={{-20,50},{20,70}}, rotation=0), - iconTransformation(extent={{-20,50},{20,70}}))); - -equation - // derivative transformations - dddt = state.dddT_pX*der(T) + state.dddp_TX*der(p) + state.dddX_pT*der(X[1]); - dhdt = state.dhdT_pX*der(T) + state.dhdp_TX*der(p) + state.dhdX_pT*der(X[1]); - - // Mass conservation - V * dddt = port.m_flow; - // species conservation - V * (X[1]*dddt + d*der(X[1])) = port.m_flow*actualStream(port.Xi_outflow[1]); - X[2] = 1-X[1]; - // energy cons - V * (d*dhdt + h*dddt - der(p)) = port.m_flow*actualStream(port.h_outflow) + heatPort.Q_flow; - -// der(u)=0; -// der(d)=0; -// der(X1)=0; - -// // Thermodynamic properties -// state = Medium.setState_phX(p,h,X); -// sat = Medium.setSat_pX(p,X[:]); -// u = Medium.specificInternalEnergy(state); -// T = Medium.temperature(state); -// h = Medium.specificEnthalpy(state); -// d = Medium.density(state); -// p = Medium.pressure(state); - - // Thermodynamic properties - state = Medium.setState_pTX(p,T,X,partialDersInputChoice=4); -// sat = Medium.setSat_pX(p,X[:]); -// u = Medium.specificInternalEnergy(state); -u = h - p/d; -// T = Medium.temperature(state); - h = Medium.specificEnthalpy(state); - d = Medium.density(state); -// p = Medium.pressure(state); - -// port connections - h = port.h_outflow; - X[1] = port.Xi_outflow[1]; -// X[2] = port.Xi_outflow[2]; - p = port.p; - T = heatPort.T; - -// additional sum test.. This shows that dddX[1] - dddX[2] is equal to dddX_num with both mass fractions varied... - -// dddX_num = (Medium.density(state_dX)-d)/0.0001; -// dddX_num_check = dddX[1] - dddX[2]; - - annotation (Diagram(graphics), Icon(coordinateSystem(preserveAspectRatio=false, - extent={{-100,-100},{100,100}}), - graphics={Ellipse( - extent={{-60,60},{60,-60}}, - lineColor={0,0,255}, - fillColor={0,0,255}, - fillPattern=FillPattern.Solid)})); -end Volume_pTX; - - -model system_MUX_sp - - Volume_MUX volume(V=0.01, hstart=3000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); - Modelica.Fluid.Sources.MassFlowSource_h boundary( - nPorts=1, - use_h_in=false, - m_flow=0, - use_m_flow_in=true, - X={0.8,0.2}, - h=3000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); -equation - connect(boundary.ports[1], volume.port) annotation (Line( - points={{58,34},{66,34},{66,0},{-16,0}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(sine.y, boundary.m_flow_in) annotation (Line( - points={{24.6,36},{30,36},{30,42},{38,42}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( - points={{-26,40},{-24,40},{-24,6},{-22,6}}, - color={191,0,0}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics)); -end system_MUX_sp; - -model system_MUX_tp - - Volume_MUX volume(V=0.01, hstart=1500e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{-32,-10},{-12,10}}))); - Modelica.Fluid.Sources.MassFlowSource_h boundary( - nPorts=1, - use_h_in=false, - m_flow=0, - use_m_flow_in=true, - X={0.8,0.2}, - h=2000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-46,30},{-26,50}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-80,36},{-68,48}}))); -equation - connect(boundary.ports[1], volume.port) annotation (Line( - points={{58,34},{66,34},{66,0},{-16,0}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-67.4,42},{-56,42},{-56,40},{-46,40}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(sine.y, boundary.m_flow_in) annotation (Line( - points={{24.6,36},{30,36},{30,42},{38,42}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(fixedHeatFlow.port, volume.heatPort) annotation (Line( - points={{-26,40},{-24,40},{-24,6},{-22,6}}, - color={191,0,0}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics)); -end system_MUX_tp; - -model system_phX_sp - - Modelica.Fluid.Sources.MassFlowSource_h boundary( - use_h_in=false, - nPorts=1, - m_flow=0, - use_m_flow_in=true, - X={0.8,0.2}, - h=3000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( - V=0.01, - hstart=3000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); -equation - connect(volume.port, boundary.ports[1]) annotation (Line( - points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( - points={{-26,8},{-18,8},{-18,38},{-20,38}}, - color={191,0,0}, - smooth=Smooth.None)); - connect(sine.y, boundary.m_flow_in) annotation (Line( - points={{24.6,36},{30,36},{30,42},{38,42}}, - color={0,0,127}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ - {-100,-100},{100,100}}))); -end system_phX_sp; - -model system_phX_tp - - Modelica.Fluid.Sources.MassFlowSource_h boundary( - use_h_in=false, - nPorts=1, - m_flow=0, - use_m_flow_in=true, - X={0.8,0.2}, - h=2000e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( - V=0.01, - hstart=1500e3, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) - annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); -equation - connect(volume.port, boundary.ports[1]) annotation (Line( - points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( - points={{-26,8},{-18,8},{-18,38},{-20,38}}, - color={191,0,0}, - smooth=Smooth.None)); - connect(sine.y, boundary.m_flow_in) annotation (Line( - points={{24.6,36},{30,36},{30,42},{38,42}}, - color={0,0,127}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ - {-100,-100},{100,100}}))); -end system_phX_tp; - -model system_pTX_sp - - Modelica.Fluid.Sources.MassFlowSource_h boundary( - use_h_in=false, - nPorts=1, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, - m_flow=0, - X={0.8,0.2}, - use_m_flow_in=true, - h=3000e3) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2, - startTime=0) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - Volume_pTX volume(V=0.01, hstart=3000e3) - annotation (Placement(transformation(extent={{-36,-8},{-16,12}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); -equation - connect(volume.port, boundary.ports[1]) annotation (Line( - points={{-20,2},{32,2},{32,0},{78,0},{78,34},{58,34}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( - points={{-26,8},{-18,8},{-18,38},{-20,38}}, - color={191,0,0}, - smooth=Smooth.None)); - connect(boundary.m_flow_in, sine.y) annotation (Line( - points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, - color={0,0,127}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ - {-100,-100},{100,100}}))); -end system_pTX_sp; - -model system_pTX_tp - - Modelica.Fluid.Sources.MassFlowSource_h boundary( - use_h_in=false, - nPorts=1, - redeclare package Medium = REFPROP2Modelica.Media.NH3_Water, - m_flow=0, - X={0.8,0.2}, - use_m_flow_in=true, - h=2000e3) - annotation (Placement(transformation(extent={{38,24},{58,44}}))); - Modelica.Blocks.Sources.Sine sine( - freqHz=5, - amplitude=0.1, - offset=0.2, - startTime=0) - annotation (Placement(transformation(extent={{12,30},{24,42}}))); - Volume_pTX volume(V=0.01, hstart=1500e3) - annotation (Placement(transformation(extent={{-38,-10},{-16,12}}))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow fixedHeatFlow - annotation (Placement(transformation(extent={{-40,28},{-20,48}}))); - Modelica.Blocks.Sources.Sine sine1( - freqHz=1, - amplitude=-5000000, - offset=0, - startTime=100) - annotation (Placement(transformation(extent={{-74,34},{-62,46}}))); -equation - connect(volume.port, boundary.ports[1]) annotation (Line( - points={{-20.4,1},{32,1},{32,0},{78,0},{78,34},{58,34}}, - color={0,127,255}, - smooth=Smooth.None)); - connect(sine1.y, fixedHeatFlow.Q_flow) annotation (Line( - points={{-61.4,40},{-50,40},{-50,38},{-40,38}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(volume.heatPort, fixedHeatFlow.port) annotation (Line( - points={{-27,7.6},{-18,7.6},{-18,38},{-20,38}}, - color={191,0,0}, - smooth=Smooth.None)); - connect(boundary.m_flow_in, sine.y) annotation (Line( - points={{38,42},{34,42},{34,38},{24.6,38},{24.6,36}}, - color={0,0,127}, - smooth=Smooth.None)); - annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, - -100},{100,100}}), graphics), Icon(coordinateSystem(extent={ - {-100,-100},{100,100}}))); -end system_pTX_tp; - - -end NH3Water_MUXvsPHXvsPTX; diff --git a/Testers/NH3_Water_setSatModel.mo b/Testers/NH3_Water_setSatModel.mo deleted file mode 100644 index 85f590f..0000000 --- a/Testers/NH3_Water_setSatModel.mo +++ /dev/null @@ -1,25 +0,0 @@ -within REFPROP2Modelica.Testers; -model NH3_Water_setSatModel - -package Medium = REFPROP2Modelica.Media.NH3_Water; - - Medium.ThermodynamicState dewstate; - Medium.ThermodynamicState bubstate; - - Medium.SaturationProperties sat; - Medium.SaturationProperties sat2; - - Medium.AbsolutePressure p; - Medium.MassFraction X[2]; - -equation - p=50e5; - X={0.5,0.5}; - - sat = Medium.setSat_pX(p,X,450,calcTransport=true); - sat2 = Medium.setSat_TX(450,X,calcTransport=true); - - dewstate = Medium.setDewState(sat); - bubstate = Medium.setBubbleState(sat); - -end NH3_Water_setSatModel; diff --git a/Testers/NH3_Water_setStateModel.mo b/Testers/NH3_Water_setStateModel.mo deleted file mode 100644 index 92ef85b..0000000 --- a/Testers/NH3_Water_setStateModel.mo +++ /dev/null @@ -1,42 +0,0 @@ -within REFPROP2Modelica.Testers; -model NH3_Water_setStateModel - -package Medium = REFPROP2Modelica.Media.NH3_Water; - - Medium.ThermodynamicState state; -// Medium.SaturationProperties sat; - - Medium.AbsolutePressure p; - Medium.SpecificEnthalpy h; - Medium.MassFraction X[2]; - Medium.Density d; - -Medium.MassFraction Xdef[Medium.nX]=Medium.X_default; - -Real q; - -Real dddh_pX; -Real dddp_hX; -Real dddh_pX_num; -Real dddp_hX_num; - -Real dddX_ph_num; - -equation - p=50e5; - h=3e5 + time*25e5; - X={0.5,0.5}; - - state = Medium.setState_phX(p,h,X,calcTransport=false,partialDersInputChoice=3); - q = Medium.vapourQuality(state); - d = Medium.density(state); - - dddh_pX = Medium.density_derh_p(state); - dddh_pX_num = Medium.density(Medium.setState_phX(p,h+1,X))-d; - - dddp_hX = Medium.density_derp_h(state); - dddp_hX_num = Medium.density(Medium.setState_phX(p+1,h,X))-d; - - dddX_ph_num = (Medium.density(Medium.setState_phX(p,h,cat(1,{X[1]+0.0001},{X[2]-0.0001})))-d)/0.0001; - -end NH3_Water_setStateModel; diff --git a/Testers/NH3_Water_setStateModel_test_partial_inputs.mo b/Testers/NH3_Water_setStateModel_test_partial_inputs.mo deleted file mode 100644 index 6ef00f1..0000000 --- a/Testers/NH3_Water_setStateModel_test_partial_inputs.mo +++ /dev/null @@ -1,32 +0,0 @@ -within REFPROP2Modelica.Testers; -model NH3_Water_setStateModel_test_partial_inputs - -package Medium = REFPROP2Modelica.Media.NH3_Water; -//package Medium2 = REFPROP2Modelica.Media.NH3_Water; - -// Medium.PartialDersInputChoice partialDersInputChoice = Medium.PartialDersInputChoice.none; -// Medium2.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.pTX_numeric; - - Medium.ThermodynamicState state; - Medium.ThermodynamicState state2; - -// input PartialDersInputChoice partialDersInputChoice=PartialDersInputChoice.none; - - Medium.AbsolutePressure p; - Medium.SpecificEnthalpy h; - Medium.MassFraction X[2]; - - parameter Medium.PartialDersInputChoice partialDersInputChoice0 = Medium.PartialDersInputChoice.none; - parameter Medium.PartialDersInputChoice partialDersInputChoice1 = Medium.PartialDersInputChoice.phX_numeric; - parameter Medium.PartialDersInputChoice partialDersInputChoice2 = Medium.PartialDersInputChoice.phX_pseudoanalytic; - parameter Medium.PartialDersInputChoice partialDersInputChoice3 = Medium.PartialDersInputChoice.pTX_numeric; - -equation - p=50e5; - h=3e5+time*100e3; - X={0.5,0.5}; - - state = Medium.setState_phX(p,h,X); - state2 = Medium.setState_phX(p,h,X,partialDersInputChoice=3); - -end NH3_Water_setStateModel_test_partial_inputs; diff --git a/Testers/PropsMixtureNH3H2O.mo b/Testers/PropsMixtureNH3H2O.mo deleted file mode 100644 index 2870728..0000000 --- a/Testers/PropsMixtureNH3H2O.mo +++ /dev/null @@ -1,41 +0,0 @@ -within REFPROP2Modelica.Testers; -model PropsMixtureNH3H2O -package Medium = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium ( - final substanceNames={"ammoniaL","water"}, - inputChoice=REFPROP2Modelica.Interfaces.MixtureInputChoice.dTX); - - Medium.ThermodynamicState state; - - Modelica.SIunits.Density d; - Modelica.SIunits.Temperature T; - Real[2] X; - - Modelica.SIunits.AbsolutePressure p; - Real q; - - Medium.SaturationProperties sat = REFPROP2Modelica.Interfaces.REFPROPMixtureTwoPhaseMedium.setSat( - p,X); - - Medium.SpecificEnthalpy hl = Medium.bubbleEnthalpy(sat); - Medium.SpecificEnthalpy hv = Medium.dewEnthalpy(sat); - - Medium.Density dl = Medium.bubbleDensity(sat); - Medium.Density dv = Medium.dewDensity(sat); - -protected - Modelica.SIunits.Temperature T_init = 400; - Real[2] X_init = {0.5,0.5}; - Modelica.SIunits.AbsolutePressure p_init = Medium.pressure_TqX(T_init,0.5,X_init); -initial algorithm - d := Medium.density_pTX(p_init,T_init,X_init); -equation - der(d) = 0; - X[1] = 0.25 + 0.5 * time; - X[2] = 1 - X[1]; - T = 350 + 100 * time; - state = Medium.setState_dTX(d,T,X); - - p = Medium.pressure(state); - q = Medium.vapourQuality(state); - -end PropsMixtureNH3H2O; diff --git a/Testers/Water_MixtureTwoPhase_pT/package.bak-mo b/Testers/Water_MixtureTwoPhase_pT/package.bak-mo deleted file mode 100644 index cd45770..0000000 --- a/Testers/Water_MixtureTwoPhase_pT/package.bak-mo +++ /dev/null @@ -1,22 +0,0 @@ -within REFPROP2Modelica.Testers; -package Water_MixtureTwoPhase_pT "(incomplete) Water model from Modelica.Media compatible to PartialMixtureTwoPhaseMedium (Example use)" - extends REFPROP2Modelica.Interfaces.PartialMixtureTwoPhaseMedium(final mediumName = "TwoPhaseMixtureWater", final substanceNames = {"water"}, final reducedX = true, final singleState = false, reference_X = cat(1, fill(0, nX - 1), {1}), fluidConstants = BrineConstants); - // final extraPropertiesNames={"gas enthalpy","liquid enthalpy"}, - constant Modelica.SIunits.MolarMass M_H2O = 0.018015 "[kg/mol] TODO"; - - annotation(Documentation(info = " -

Water_MixtureTwoPhase_pT

- This is a an example use of PartialMixtureTwoPhaseMedium. - It is a (incomplete) water model using the template PartialMixtureTwoPhaseMedium. It uses the property functions from Modelica.Media.Water.
- -

Created by

-Henning Francke
-Helmholtz Centre Potsdam
-GFZ German Research Centre for Geosciences
-Telegrafenberg, D-14473 Potsdam
-Germany -

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.mo b/Testers/package.mo index 67a63ea..878288f 100644 --- a/Testers/package.mo +++ b/Testers/package.mo @@ -1,3 +1,9 @@ within REFPROP2Modelica; package Testers + + + + + + end Testers; diff --git a/Testers/package.order b/Testers/package.order index 4b136de..4f27931 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -4,7 +4,4 @@ PropsMixtureTwo PropsPureSubstance R410mixTester Water_MixtureTwoPhase_pT -PropsMixtureNH3H2O -NH3_Water_setSatModel -NH3_Water_setStateModel -numerical_jacobian_test_setState_ph +AmmoniaWater From 28eb9ade9a973377a36d524dfe7b65e411403f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ryhl=20K=C3=A6rn?= Date: Mon, 16 Jun 2014 14:09:07 +0200 Subject: [PATCH 57/57] Minor bug.. --- Testers/AmmoniaWater.mo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Testers/AmmoniaWater.mo b/Testers/AmmoniaWater.mo index 1a523d2..43090ce 100644 --- a/Testers/AmmoniaWater.mo +++ b/Testers/AmmoniaWater.mo @@ -501,7 +501,7 @@ package AmmoniaWater amplitude=0.1, offset=0.2) annotation (Placement(transformation(extent={{12,30},{24,42}}))); - REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + Volume_phX volume( V=0.01, hstart=3000e3, redeclare package Medium = REFPROP2Modelica.Media.NH3_Water) @@ -552,7 +552,7 @@ package AmmoniaWater amplitude=0.1, offset=0.2) annotation (Placement(transformation(extent={{12,30},{24,42}}))); - REFPROP2Modelica.Testers.NH3Water_MUXvsPHXvsPTX.Volume_phX volume( + Volume_phX volume( V=0.01, hstart=1500e3, redeclare package Medium = REFPROP2Modelica.Media.NH3_Water)

-francke@gfz-potsdam.de - -")); -end Water_MixtureTwoPhase_pT; diff --git a/Testers/package.order b/Testers/package.order index cbda809..1b48ebf 100644 --- a/Testers/package.order +++ b/Testers/package.order @@ -3,5 +3,4 @@ PropsMixture PropsMixtureTwo PropsPureSubstance R410mixTester -Water_MixtureTwoPhase_pT PropsMixtureNH3H2O diff --git a/_wrapper/src/refprop_wrapper.cpp b/_wrapper/src/refprop_wrapper.cpp index 945017d..66665b7 100644 --- a/_wrapper/src/refprop_wrapper.cpp +++ b/_wrapper/src/refprop_wrapper.cpp @@ -803,6 +803,12 @@ double initRefprop() { printf("check types and names in header file.\n"); return FAIL; } + // Set the desired equation of state, consult the Refprop + // documentation for more details. + // 0 : use default values + // 2 : force Peng-Robinson + long eosSwitch = 0; + PREOSdll(eosSwitch); return OK; } else { if (debug) printf ("Library loaded, not doing anything.\n"); diff --git a/package.mo b/package.mo index 9285011..273e63d 100644 --- a/package.mo +++ b/package.mo @@ -1,27 +1,17 @@ within ; package REFPROP2Modelica constant String REFPROP_PATH = "C:\\Program Files\\REFPROP"; -// constant String REFPROP_PATH = "/opt/refprop"; + // constant String REFPROP_PATH = "/opt/refprop"; - - - annotation (version="0.2", uses(Modelica(version="3.2")), - Documentation(info=" -