Merge pull request #536 from JonWel/master

Add low level interface to Julia wrapper as discussed in #534
This commit is contained in:
Ian Bell
2015-03-12 15:40:33 +01:00
4 changed files with 289 additions and 13 deletions

View File

@@ -25,6 +25,46 @@ which yields the output:
.. literalinclude:: snippets/AbstractState1.cxx.output
Here is an example of the shared library usage with Julia wrapper::
julia> import CoolProp
julia> PT_INPUTS = CoolProp.get_input_pair_index("PT_INPUTS")
7
julia> cpmass = CoolProp.get_param_index("C")
34
julia> handle = CoolProp.AbstractState_factory("HEOS", "Water")
0
julia> CoolProp.AbstractState_update(handle,PT_INPUTS,101325, 300)
julia> CoolProp.AbstractState_keyed_output(handle,cpmass)
4180.635776569655
julia> CoolProp.AbstractState_free(handle)
julia> handle = CoolProp.AbstractState_factory("HEOS", "Water&Ethanol")
1
julia> PQ_INPUTS = CoolProp.get_input_pair_index("PQ_INPUTS")
2
julia> T = CoolProp.get_param_index("T")
18
julia> CoolProp.AbstractState_set_fractions(handle, [0.4, 0.6])
julia> CoolProp.AbstractState_update(handle,PQ_INPUTS,101325, 0)
julia> CoolProp.AbstractState_keyed_output(handle,T)
352.3522142890429
julia> CoolProp.AbstractState_free(handle)
julia>
Alternatively, the :cpapi:`AbstractState::keyed_output` function can be called with the appropriate key from :cpapi:`CoolProp::parameters`. There should be essentially no difference in speed between these two methods.
Similar methodology is used in the other wrappers of the low-level interface to (mostly) generate 1-to-1 wrappers of the low-level functions to the target language. Refer to the examples for each language to see how to call the low-level interface, generate an AbstractState instance, etc.

View File

@@ -25,12 +25,26 @@ The wrapper should be valid for Julia 0.4 and above. For Julia 0.3 and lower, us
Usage
-----
At the console, do something like this in the folder that contains CoolProp.jl and the shared library::
At the console, do something like this in the folder that contains CoolProp.jl and the shared library:
High level interface::
julia> import CoolProp
julia> CoolProp.PropsSI("T","P",101325.0,"Q",0.0,"Water")
373.1242958476879
Low level interface::
julia> handle = CoolProp.AbstractState_factory("HEOS", "Water")
0
julia> CoolProp.AbstractState_update(handle,CoolProp.get_input_pair_index("PT_INPUTS"),101325, 300)
julia> CoolProp.AbstractState_keyed_output(handle,CoolProp.get_param_index("C"))
4180.635776569655
julia> CoolProp.AbstractState_free(handle)
Option B: Using PyCall package in Julia
=======================================

View File

@@ -1,6 +1,6 @@
module CoolProp
export F2K, K2F, HAPropsSI, PropsSI, PhaseSI, get_global_param_string, get_param_index
export F2K, K2F, HAPropsSI, PropsSI, PhaseSI, get_global_param_string, get_param_index, get_input_pair_index, AbstractState_factory, AbstractState_free, AbstractState_update, AbstractState_keyed_output
function F2K(TF::Number)
return ccall( (:F2K, "CoolProp"), Cdouble, (Cdouble,), TF)
@@ -13,7 +13,7 @@ end
function HAPropsSI(Output::String, Name1::String, Value1::Number, Name2::String, Value2::Number, Name3::String, Value3::Number)
val = ccall( (:HAPropsSI, "CoolProp"), Cdouble, (Ptr{Uint8},Ptr{Uint8},Float64,Ptr{Uint8},Float64,Ptr{Uint8},Float64), Output,Name1,Value1,Name2,Value2,Name3,Value3)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -21,7 +21,7 @@ end
function PropsSI(Output::String, Name1::String, Value1::Number, Name2::String, Value2::Number, Fluid::String)
val = ccall( (:PropsSI, "CoolProp"), Cdouble, (Ptr{Uint8},Ptr{Uint8},Float64,Ptr{Uint8},Float64,Ptr{Uint8}), Output,Name1,Value1,Name2,Value2,Fluid)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -29,7 +29,7 @@ end
function PropsSI(FluidName::String, Output::String)
val = ccall( (:Props1SI, "CoolProp"), Cdouble, (Ptr{Uint8},Ptr{Uint8}), FluidName,Output)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -48,9 +48,120 @@ function get_global_param_string(Key::String)
end
# Get the index for a parameter "T", "P", etc.
# returns the index as a long. If input is invalid, returns -1
# returns the index as a long.
function get_param_index(Param::String)
return ccall( (:get_param_index, "CoolProp"), Clong, (Ptr{Uint8},), Param)
val = ccall( (:get_param_index, "CoolProp"), Clong, (Ptr{Uint8},), Param)
if val == -1
error("CoolProp: Unknown parameter: ", Param)
end
return val
end
# Get the index for an input pair for AbstractState.update function
# returns the index as a long.
function get_input_pair_index(Param::String)
val = ccall( (:get_input_pair_index, "CoolProp"), Clong, (Ptr{Uint8},), Param)
if val == -1
error("CoolProp: Unknown input pair: ", Param)
end
return val
end
# ---------------------------------
# Low-level access
# ---------------------------------
errcode = Array(Clong, 1)
buffer_length = 255
message_buffer = Array(Uint8, buffer_length)
# Generate an AbstractState instance, return an integer handle to the state class generated to be used in the other low-level accessor functions
# param backend The backend you will use, "HEOS", "REFPROP", etc.
# param fluids '&' delimited list of fluids
# return A handle to the state class generated
function AbstractState_factory(backend::String, fluids::String)
AbstractState = ccall( (:AbstractState_factory, "CoolProp"), Clong, (Ptr{Uint8},Ptr{Uint8},Ptr{Clong},Ptr{Uint8},Clong), backend,fluids,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{Uint8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return AbstractState
end
# Release a state class generated by the low-level interface wrapper
# param handle The integer handle for the state class stored in memory
function AbstractState_free(handle::Clong)
ccall( (:AbstractState_free, "CoolProp"), Void, (Clong,Ptr{Clong},Ptr{Uint8},Clong), handle,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{Uint8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Set the fractions (mole, mass, volume) for the AbstractState
# param handle The integer handle for the state class stored in memory
# param fractions The array of fractions
function AbstractState_set_fractions(handle::Clong,fractions::Array)
ccall( (:AbstractState_set_fractions, "CoolProp"), Void, (Clong,Ptr{Cdouble},Clong,Ptr{Clong},Ptr{Uint8},Clong), handle,fractions,length(fractions),errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{Uint8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Update the state of the AbstractState
# param handle The integer handle for the state class stored in memory
# param input_pair The integer value for the input pair obtained from get_input_pair_index(Param::String)
# param value1 The first input value
# param value2 The second input value
function AbstractState_update(handle::Clong,input_pair::Clong,value1::Number,value2::Number)
ccall( (:AbstractState_update, "CoolProp"), Void, (Clong,Clong,Cdouble,Cdouble,Ptr{Clong},Ptr{Uint8},Clong), handle,input_pair,value1,value2,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{Uint8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Get an output value from the AbstractState using an integer value for the desired output value
# param handle The integer handle for the state class stored in memory
# param param The integer value for the parameter you want
function AbstractState_keyed_output(handle::Clong, param::Clong)
output = ccall( (:AbstractState_keyed_output, "CoolProp"), Cdouble, (Clong,Clong,Ptr{Clong},Ptr{Uint8},Clong), handle,param,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{Uint8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
elseif output == -Inf
error("CoolProp: no correct state has been set with AbstractState_update")
end
return output
end
end #module

View File

@@ -1,6 +1,6 @@
module CoolProp
export F2K, K2F, HAPropsSI, PropsSI, PhaseSI, get_global_param_string, get_param_index
export F2K, K2F, HAPropsSI, PropsSI, PhaseSI, get_global_param_string, get_param_index, get_input_pair_index, AbstractState_factory, AbstractState_free, AbstractState_update, AbstractState_keyed_output
function F2K(TF::Number)
return ccall( (:F2K, "CoolProp"), Cdouble, (Cdouble,), TF)
@@ -13,7 +13,7 @@ end
function HAPropsSI(Output::String, Name1::String, Value1::Number, Name2::String, Value2::Number, Name3::String, Value3::Number)
val = ccall( (:HAPropsSI, "CoolProp"), Cdouble, (Ptr{UInt8},Ptr{UInt8},Float64,Ptr{UInt8},Float64,Ptr{UInt8},Float64), Output,Name1,Value1,Name2,Value2,Name3,Value3)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -21,7 +21,7 @@ end
function PropsSI(Output::String, Name1::String, Value1::Number, Name2::String, Value2::Number, Fluid::String)
val = ccall( (:PropsSI, "CoolProp"), Cdouble, (Ptr{UInt8},Ptr{UInt8},Float64,Ptr{UInt8},Float64,Ptr{UInt8}), Output,Name1,Value1,Name2,Value2,Fluid)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -29,7 +29,7 @@ end
function PropsSI(FluidName::String, Output::String)
val = ccall( (:Props1SI, "CoolProp"), Cdouble, (Ptr{UInt8},Ptr{UInt8}), FluidName,Output)
if val == Inf
error("CoolProp:", get_global_param_string("errstring"))
error("CoolProp: ", get_global_param_string("errstring"))
end
return val
end
@@ -48,9 +48,120 @@ function get_global_param_string(Key::String)
end
# Get the index for a parameter "T", "P", etc.
# returns the index as a long. If input is invalid, returns -1
# returns the index as a long.
function get_param_index(Param::String)
return ccall( (:get_param_index, "CoolProp"), Clong, (Ptr{UInt8},), Param)
val = ccall( (:get_param_index, "CoolProp"), Clong, (Ptr{UInt8},), Param)
if val == -1
error("CoolProp: Unknown parameter: ", Param)
end
return val
end
# Get the index for an input pair for AbstractState.update function
# returns the index as a long.
function get_input_pair_index(Param::String)
val = ccall( (:get_input_pair_index, "CoolProp"), Clong, (Ptr{UInt8},), Param)
if val == -1
error("CoolProp: Unknown input pair: ", Param)
end
return val
end
# ---------------------------------
# Low-level access
# ---------------------------------
errcode = Ref{Clong}(0)
buffer_length = 255
message_buffer = Array(UInt8, buffer_length)
# Generate an AbstractState instance, return an integer handle to the state class generated to be used in the other low-level accessor functions
# param backend The backend you will use, "HEOS", "REFPROP", etc.
# param fluids '&' delimited list of fluids
# return A handle to the state class generated
function AbstractState_factory(backend::String, fluids::String)
AbstractState = ccall( (:AbstractState_factory, "CoolProp"), Clong, (Ptr{UInt8},Ptr{UInt8},Ref{Clong},Ptr{UInt8},Clong), backend,fluids,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{UInt8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return AbstractState
end
# Release a state class generated by the low-level interface wrapper
# param handle The integer handle for the state class stored in memory
function AbstractState_free(handle::Clong)
ccall( (:AbstractState_free, "CoolProp"), Void, (Clong,Ref{Clong},Ptr{UInt8},Clong), handle,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{UInt8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Set the fractions (mole, mass, volume) for the AbstractState
# param handle The integer handle for the state class stored in memory
# param fractions The array of fractions
function AbstractState_set_fractions(handle::Clong,fractions::Array)
ccall( (:AbstractState_set_fractions, "CoolProp"), Void, (Clong,Ptr{Cdouble},Clong,Ref{Clong},Ptr{UInt8},Clong), handle,fractions,length(fractions),errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{UInt8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Update the state of the AbstractState
# param handle The integer handle for the state class stored in memory
# param input_pair The integer value for the input pair obtained from get_input_pair_index(Param::String)
# param value1 The first input value
# param value2 The second input value
function AbstractState_update(handle::Clong,input_pair::Clong,value1::Number,value2::Number)
ccall( (:AbstractState_update, "CoolProp"), Void, (Clong,Clong,Cdouble,Cdouble,Ref{Clong},Ptr{UInt8},Clong), handle,input_pair,value1,value2,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{UInt8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
end
return nothing
end
# Get an output value from the AbstractState using an integer value for the desired output value
# param handle The integer handle for the state class stored in memory
# param param The integer value for the parameter you want
function AbstractState_keyed_output(handle::Clong, param::Clong)
output = ccall( (:AbstractState_keyed_output, "CoolProp"), Cdouble, (Clong,Clong,Ref{Clong},Ptr{UInt8},Clong), handle,param,errcode,message_buffer,buffer_length)
if errcode[] != 0
if errcode[] == 1
error("CoolProp: ", bytestring(convert(Ptr{UInt8}, pointer(message_buffer))))
elseif errcode[] == 2
error("CoolProp: message buffer too small")
else # == 3
error("CoolProp: unknown error")
end
elseif output == -Inf
error("CoolProp: no correct state has been set with AbstractState_update")
end
return output
end
end #module