diff --git a/wrappers/Lua/Makefile b/wrappers/Lua/Makefile index 235f1ebd..5d248cb6 100644 --- a/wrappers/Lua/Makefile +++ b/wrappers/Lua/Makefile @@ -8,7 +8,7 @@ COOLPROP_LIBDIR ?= $(shell $(PKGCONFIG) --variable=libdir CoolProp) COOLPROP_HEADER ?= $(or $(COOLPROP_INCDIR) CFLAGS ?= -g -O2 -Wall -Wextra -Wswitch-enum -Wwrite-strings -Wshadow -XCFLAGS += -std=c99 -pedantic-errors -fpic +XCFLAGS += -std=c99 -pedantic-errors -fPIC XCFLAGS += $(LUA_CFLAGS) $(COOLPROP_CFLAGS) XLDFLAGS += $(GUMBO_LDFLAGS) $(COOLPROP_LDLIBS) @@ -16,9 +16,21 @@ all: coolprop/capi.so coolprop/capi.o: coolprop/capi.c coolprop/compat.h +install: all + $(MKDIR) '$(DESTDIR)$(LUA_CMOD_DIR)/coolprop' + $(MKDIR) '$(DESTDIR)$(LUA_LMOD_DIR)/coolprop' + $(INSTALLX) coolprop/capi.so '$(DESTDIR)$(LUA_CMOD_DIR)/coolprop/capi.so' + $(INSTALL) coolprop.lua '$(DESTDIR)$(LUA_LMOD_DIR)/' + $(INSTALL) coolprop/ffi.lua '$(DESTDIR)$(LUA_LMOD_DIR)/coolprop/' + +uninstall: + $(RM) '$(DESTDIR)$(LUA_LMOD_DIR)/coolprop.lua' + $(RM) -r '$(DESTDIR)$(LUA_CMOD_DIR)/coolprop/' + $(RM) -r '$(DESTDIR)$(LUA_LMOD_DIR)/coolprop/' + clean: $(RM) coolprop/capi.so coolprop/capi.o -.PHONY: all +.PHONY: all install uninstall clean .DELETE_ON_ERROR: diff --git a/wrappers/Lua/README.rst b/wrappers/Lua/README.rst index dbbdbcd9..82bde504 100644 --- a/wrappers/Lua/README.rst +++ b/wrappers/Lua/README.rst @@ -3,4 +3,186 @@ Lua Wrapper for CoolProp Lua C API and LuaJIT wrappers for CoolProp library (currently implementing the high-level C API). -by Aapo Talvensaari, Helsinki, Finland, January 2015 \ No newline at end of file +by Aapo Talvensaari, Helsinki, Finland, January 2015 + + +Hello World with Lua Wrapper +---------------------------- + +:: + + local cp = require "coolprop" + print(cp.Props1SI("Water", "D")) + + +Installation +------------ + +This wrapper comes with a support for both LuaJIT FFI and PUC-Lua C-API. + +**Installing with Make** + +1. Run ``make`` +2. Run ``make install`` +3. Done. + +**Manual Lua (PUC) Installation** + +1. First you need to build shared library version of a CoolLib library and install it somewhere in your operating system's library search path. +2. Next you need to compile ``coolprop/cpapi.c`` wrapper. Easiest way to do it is to run ``make`` on Lua wrapper's root folder. +3. Then place the resulting ``coolprop/cpapi.so`` in your Lua's ``package.cpath``, and there under ``coolprop`` directory. +4. Done. + +**Manual LuaJIT Installation** + +1. First you need to build shared library version of a CoolLib library and install it somewhere in your operating system's library search path. +2. Next you need to place ``coolprop.lua`` and ``coolprop/ffi.lua`` somewhere in your LuaJIT's ``package.path`` so that the LuaJIT can pick them up. +3. Done. + + +Lua API +------- + +The functions will in general return ``nil`` on error. + +**``number, string coolprop.PropsSI(output, name1, prop1, name2, prop2, ref)``** + +For many users, all that is needed is a simple call to the ``PropsSI`` function for pure fluids, pseudo-pure fluids +and mixtures. This function will return ``nil`` on error, and additional string that contains the error message. + +:: + local cp = require "coolprop" + print(cp.PropsSI("C", "P", 101325, "T", 300, "Water")) + print(cp.PropsSI("d(Hmass)/d(T)|P", "P", 101325, "T", 300, "Water")) + print(cp.PropsSI("D", "P", 101325, "T", 300, "Air.mix")) + + +**``number, string coolprop.Props1SI(fluidname, output)``** + +:: + local cp = require "coolprop" + print(cp.Props1SI("Water", "Phase")) + + +**``string coolprop.PhaseSI(name1, prop1, name2, prop2, ref)``** + +:: + local cp = require "coolprop" + print(cp.PhaseSI("P", 101325, "Q", 0, "Water")) + + +**``number, string coolprop.HAPropsSI(output, name1, prop1, name2, prop2, name3, prop3)``** + +:: + local cp = require "coolprop" + print(cp.HAPropsSI('H','T',298.15,'P',101325,'R',0.5)) + + +**``string coolprop.get_global_param_string(param)``** + +Returns global parameter string. On error, returns ``nil``. + +:: + local cp = require "coolprop" + print(cp.get_global_param_string("predefined_mixtures")) + + +**``number coolprop.get_param_index(param)``** + +Returns parameter index. + +:: + local cp = require "coolprop" + print(cp.get_param_index("T")) + + +**``number coolprop.F2K(f)``** + +This function converts fahrenheits to kelvins. + +:: + local cp = require "coolprop" + print(10, "Fahrenheits is", cp.F2K(10) , "Kelvins") + + +**``number coolprop.K2F(f)``** + +This function converts kelvins to fahrenheits. + +:: + local cp = require "coolprop" + print(cp.F2K(10), "Kelvins is", cp.K2F(cp.F2K(10)), "Fahrenheits") + + +**``string coolprop.error()``** + +Returns the last error occurred. + +:: + local cp = require "coolprop" + print(cp.error()) + + +**``string coolprop.FluidsList()``** + +Returns the list of available fluids. + +:: + local cp = require "coolprop" + print(cp.FluidsList()) + + +**``string coolprop.version()``** + +Returns the version of the CoolLib library that is installed. + +:: + local cp = require "coolprop" + print(cp.version()) + + +**``string coolprop.gitrevision()``** + +Returns the Git revision of the CoolLib library that is installed. + +:: + local cp = require "coolprop" + print(cp.gitrevision()) + + +**``number coolprop.get_debug_level()``** + +Returns the current debug level. + +:: + local cp = require "coolprop" + print(cp.get_debug_level()) + + +**``coolprop.set_debug_level(level)``** + +Sets the debug level. + +:: + local cp = require "coolprop" + cp.set_debug_level(0) + + +**``boolean coolprop.redirect_stdout(file)``** + +Sets the output to a file (to given path of the file). + +:: + local cp = require "coolprop" + cp.redirect_stdout("output.log") + + +Additional APIs (TBD) +--------------------- + +**``string coolprop.get_parameter_information_string(key)``** +**``number coolprop.get_mixture_binary_pair_data(cas1, cas2, key)``** +**``string coolprop.get_fluid_param_string(fluid, param)``** +**``boolean coolprop.set_reference_stateS(ref, state)``** +**``boolean coolprop.set_reference_stateD(ref, t, rho, h0, s0)``** +**``number, string coolprop.saturation_ancillary(fluid, output, q, input, value)``** diff --git a/wrappers/Lua/coolprop.lua b/wrappers/Lua/coolprop.lua index 7a1da887..33133bb4 100644 --- a/wrappers/Lua/coolprop.lua +++ b/wrappers/Lua/coolprop.lua @@ -1,26 +1,21 @@ if jit and jit.status() then return require "coolprop.ffi" end - local huge = math.huge - local ok, lib = pcall(require, "coolprop.capi") -assert(ok, "Unable to load CoolProp. Please check that the CoolProp is available. Both the Lua C API wrapper, and the CoolProp shared library.") +assert(ok, "Unable to load Lua CoolProp C API Wrapper.") local coolprop = {} -function coolprop.err() - return coolprop.get_global_param_string("errstring") -end function coolprop.Props1SI(fluidname, output) local v = lib.Props1SI(fluidname, output) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end function coolprop.PropsSI(output, name1, prop1, name2, prop2, ref) local v = lib.PropsSI(output, name1, prop1, name2, prop2, ref) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end @@ -64,7 +59,11 @@ function coolprop.get_param_index(param) return lib.get_param_index(param) end function coolprop.saturation_ancillary(fluid, output, q, input, value) - return lib.saturation_ancillary(fluid, output, q, input, value) + local v = lib.saturation_ancillary(fluid, output, q, input, value) + if v == huge then + return nil, coolprop.error() + end + return v end function coolprop.redirect_stdout(file) return lib.redirect_stdout(file) == 1 @@ -78,8 +77,11 @@ end function coolprop.HAPropsSI(output, name1, prop1, name2, prop2, name3, prop3) local v = lib.HAPropsSI(output, name1, prop1, name2, prop2, name3, prop3) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end +function coolprop.error() + return coolprop.get_global_param_string("errstring") +end return coolprop \ No newline at end of file diff --git a/wrappers/Lua/coolprop/compat.h b/wrappers/Lua/coolprop/compat.h index e2345bfc..2630cdba 100644 --- a/wrappers/Lua/coolprop/compat.h +++ b/wrappers/Lua/coolprop/compat.h @@ -8,4 +8,4 @@ #if LUA_VERSION_NUM < 502 # define luaL_newlib(L, l) (lua_newtable(L), luaL_register(L, NULL, l)) -#endif \ No newline at end of file +#endif diff --git a/wrappers/Lua/coolprop/ffi.lua b/wrappers/Lua/coolprop/ffi.lua index a5e95f39..c589a20d 100644 --- a/wrappers/Lua/coolprop/ffi.lua +++ b/wrappers/Lua/coolprop/ffi.lua @@ -4,6 +4,7 @@ local ffi_str = ffi.string local ffi_load = ffi.load local ffi_cdef = ffi.cdef local ffi_typeof = ffi.typeof +local pcall = pcall local huge = math.huge ffi_cdef[[ double Props1SI(const char *FluidName, const char* Output); @@ -32,21 +33,18 @@ local bub = ffi_new(but, 4096) local ok, lib = pcall(ffi_load, "CoolProp") if not ok then ok, lib = pcall(ffi_load, "coolprop") end assert(ok, "Unable to load CoolProp. Please check that the CoolProp shared library is in a default search path for dynamic libraries of your operating system.") -local coolprop = newtab(0, 18) -function coolprop.err() - return coolprop.get_global_param_string("errstring") -end +local coolprop = newtab(0, 21) function coolprop.Props1SI(fluidname, output) local v = lib.Props1SI(fluidname, output) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end function coolprop.PropsSI(output, name1, prop1, name2, prop2, ref) local v = lib.PropsSI(output, name1, prop1, name2, prop2, ref) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end @@ -63,9 +61,8 @@ function coolprop.get_global_param_string(param) return nil end function coolprop.get_parameter_information_string(key) - if lib.get_parameter_information_string(key, bub, 4096) == 1 then - return ffi_str(bub) - end + local ok, value = pcall(lib.get_parameter_information_string, key, bub, 4096) + if ok and value == 1 then return ffi_str(bub) end return nil end function coolprop.get_mixture_binary_pair_data(cas1, cas2, key) @@ -90,10 +87,16 @@ function coolprop.K2F(k) return lib.K2F(k) end function coolprop.get_param_index(param) - return tonumber(lib.get_param_index(param)) + local ok, value = pcall(lib.get_param_index, param) + if ok then return tonumber(value) end + return nil end function coolprop.saturation_ancillary(fluid, output, q, input, value) - return lib.saturation_ancillary(fluid, output, q, input, value) + local v = lib.saturation_ancillary(fluid, output, q, input, value) + if v == huge then + return nil, coolprop.error() + end + return v end function coolprop.redirect_stdout(file) return lib.redirect_stdout(file) == 1 @@ -107,8 +110,20 @@ end function coolprop.HAPropsSI(output, name1, prop1, name2, prop2, name3, prop3) local v = lib.HAPropsSI(output, name1, prop1, name2, prop2, name3, prop3) if v == huge then - return nil, coolprop.err() + return nil, coolprop.error() end return v end +function coolprop.error() + return coolprop.get_global_param_string("errstring") +end +function coolprop.FluidsList() + return coolprop.get_global_param_string("FluidsList") +end +function coolprop.version() + return coolprop.get_global_param_string("version") +end +function coolprop.gitrevision() + return coolprop.get_global_param_string("gitrevision") +end return coolprop diff --git a/wrappers/Lua/example.lua b/wrappers/Lua/example.lua index 4ce91c7a..847a065b 100644 --- a/wrappers/Lua/example.lua +++ b/wrappers/Lua/example.lua @@ -1,13 +1,41 @@ -local c = require "coolprop" +local cp = require "coolprop" -print(c.PropsSI("XX", "T", 298.15, "P", 101325, "Nitrogen")) -print(c.PropsSI("C", "P", 101325, "T", 300, "Water")) -print(c.PropsSI("d(Hmass)/d(T)|P", "P", 101325, "T", 300, "Water")) -print(c.PropsSI("D", "P", 101325, "T", 300, "Air.mix")) -print(c.PhaseSI("PXX", 101325, "Q", 0, "Water")) -print(c.get_global_param_string("predefined_mixtures")) -print(c.get_param_index("T")) -print(c.HAPropsSI('H','T',298.15,'P',101325,'R',0.5)) -print(c.HAPropsSI('HXXX','T',298.15,'P',101325,'R',0.5)) -print(c.F2K(10)) -print(c.K2F(c.F2K(10))) \ No newline at end of file +print[[ + +Information Examples +==================== +]] +print("Version", cp.version()) +print("gitrevision", cp.gitrevision()) +print("FluidsList", cp.FluidsList()) +print("Debug Level", cp.get_debug_level()) +print() +print[[ + +Usage Examples +============== +]] +print(cp.Props1SI("Water", "Phase")) +print(cp.PropsSI("C", "P", 101325, "T", 300, "Water")) +print(cp.PropsSI("d(Hmass)/d(T)|P", "P", 101325, "T", 300, "Water")) +print(cp.PropsSI("D", "P", 101325, "T", 300, "Air.mix")) +print(cp.PhaseSI("P", 101325, "Q", 0, "Water")) +print(cp.get_global_param_string("predefined_mixtures")) +print(cp.get_param_index("T")) +print(cp.HAPropsSI('H','T',298.15,'P',101325,'R',0.5)) +print(10, "Fahrenheits is", cp.F2K(10) , "Kelvins") +print(cp.F2K(10), "Kelvins is", cp.K2F(cp.F2K(10)), "Fahrenheits") +print() +print[[ + +Error Examples +============== +]] +print(cp.Props1SI("Error", "Phase")) +print(cp.PropsSI("Error", "T", 298.15, "P", 101325, "Nitrogen")) +print(cp.PhaseSI("Error", 101325, "Q", 0, "Water")) +print(cp.get_parameter_information_string("Error")) -- What are the correct inputs for this? +print(cp.saturation_ancillary("Water", "C", 10, "Error", 300)) -- What are the correct inputs for this? +print(cp.HAPropsSI('Error','T',298.15,'P',101325,'R',0.5)) +print(cp.get_param_index("Error")) +print() \ No newline at end of file