Skip to content

Commit

Permalink
ENH: Start migrating C API to its own sources + headers. Write C API …
Browse files Browse the repository at this point in the history
…as ciapws.
  • Loading branch information
MilanSkocic committed Jun 12, 2024
1 parent 3a8b73e commit 7ff5502
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 268 deletions.
File renamed without changes.
24 changes: 12 additions & 12 deletions example/example_in_f.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ program example_in_f
use iapws
implicit none
integer(int32) :: i, ngas
real(real64) :: T(1), kh(1), kd(1)
real(real64) :: T(1), kh_res(1), kd_res(1)
character(len=2) :: gas = "O2"
integer(int32) :: heavywater = 0
type(iapws_g704_gas_t), pointer :: gases_list(:)
type(gas_type), pointer :: gases_list(:)
character(len=:), pointer :: gases_str

print *, '########################## IAPWS VERSION ##########################'
Expand All @@ -25,29 +25,29 @@ program example_in_f
print *, '########################## IAPWS G7-04 ##########################'
! Compute kh and kd in H2O
T(1) = 25.0d0
call iapws_g704_kh(T, gas, heavywater, kh)
print "(A10, 1X, A10, 1X, A2, F10.1, A, 4X, A3, SP, F10.4)", "Gas=", gas, "T=", T, "C", "kh=", kh
call kh(T, gas, heavywater, kh_res)
print "(A10, 1X, A10, 1X, A2, F10.1, A, 4X, A3, SP, F10.4)", "Gas=", gas, "T=", T, "C", "kh=", kh_res

call iapws_g704_kd(T, gas, heavywater, kd)
print "(A10, 1X, A10, 1X, A2, F10.1, A, 4X, A3, SP, F15.4)", "Gas=", gas, "T=", T, "C", "kh=", kd
call kd(T, gas, heavywater, kd_res)
print "(A10, 1X, A10, 1X, A2, F10.1, A, 4X, A3, SP, F15.4)", "Gas=", gas, "T=", T, "C", "kh=", kd_res

! Get and print available gases
heavywater = 0
ngas = iapws_g704_ngases(heavywater)
ngas = ngases(heavywater)
gases_list => null()
gases_list => iapws_g704_gases(heavywater)
gases_str => iapws_g704_gases2(heavywater)
gases_list => gases(heavywater)
gases_str => gases2(heavywater)
print *, "Gases in H2O: ", ngas
print *, gases_str
do i=1, ngas
print *, gases_list(i)%gas
enddo

heavywater = 1
ngas = iapws_g704_ngases(heavywater)
ngas = ngases(heavywater)
gases_list => null()
gases_list => iapws_g704_gases(heavywater)
gases_str => iapws_g704_gases2(heavywater)
gases_list => gases(heavywater)
gases_str => gases2(heavywater)
print *, "Gases in D2O: ", ngas
print *, gases_str
do i=1, ngas
Expand Down
9 changes: 6 additions & 3 deletions fpm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ library = true
name = "example_in_f"
main = "example_in_f.f90"

[[example]]
name = "example_in_c"
main = "example_in_c.c"
#[[example]]
#name = "example_in_c"
#main = "example_in_c.c"

[[test]]
name = "tester"
main = "tester.f90"

[dependencies]
stdlib = "*"

[test.dependencies]
test-drive = {git="https://github.com/fortran-lang/test-drive", tag="v0.4.0"}
14 changes: 5 additions & 9 deletions include/iapws.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/**
* @file iapws.h
* @brief Main C header for the IAPWS library.
*/
#ifndef IAPWS_H
#define IAPWS_H
#include "iapws_version.h"
#include "iapws_g704.h"
#include "iapws_r283.h"
#ifndef CIAPWS_H
#define CIAPWS_H
#include "ciapws_version.h"
#include "ciapws_g704.h"
#include "ciapws_r283.h"
#endif
19 changes: 7 additions & 12 deletions include/iapws_g704.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
/**
* @file iapws_g704.h
* @brief C header for the module iapws_g704.
*/
#ifndef CIAPWS_G704_H
#define CIAPWS_G704_H

#ifndef IAPWS_G704_H
#define IAPWS_G704_H

extern void iapws_g704_capi_kh(double *T, char *gas, int heavywater, double *k, int size_gas, size_t size_T);
extern void iapws_g704_capi_kd(double *T, char *gas, int heavywater, double *k, int size_gas, size_t size_T);
extern int iapws_g704_capi_ngases(int heavywater);
extern char **iapws_g704_capi_gases(int heavywater);
extern char *iapws_g704_capi_gases2(int heavywater);
extern void ciapws_g704_capi_kh(double *T, char *gas, int heavywater, double *k, int size_gas, size_t size_T);
extern void ciapws_g704_capi_kd(double *T, char *gas, int heavywater, double *k, int size_gas, size_t size_T);
extern int ciapws_g704_capi_ngases(int heavywater);
extern char **ciapws_g704_capi_gases(int heavywater);
extern char *ciapws_g704_capi_gases2(int heavywater);

#endif
21 changes: 8 additions & 13 deletions include/iapws_r283.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
/**
* @file iapws_r283.h
* @brief C header for the module iapws_r283.
*/

#ifndef IAPWS_R283_H
#define IAPWS_R283_H
#ifndef CIAPWS_R283_H
#define CIAPWS_R283_H

#if _MSC_VER
#define ADD_IMPORT __declspec(dllimport)
#else
#define ADD_IMPORT
#endif

ADD_IMPORT extern const double iapws_Tc_H2O;
ADD_IMPORT extern const double iapws_Tc_D2O;
ADD_IMPORT extern const double ciapws_Tc_H2O;
ADD_IMPORT extern const double ciapws_Tc_D2O;

ADD_IMPORT extern const double iapws_pc_H2O;
ADD_IMPORT extern const double iapws_pc_D2O;
ADD_IMPORT extern const double ciapws_pc_H2O;
ADD_IMPORT extern const double ciapws_pc_D2O;

ADD_IMPORT extern const double iapws_rhoc_H2O;
ADD_IMPORT extern const double iapws_rhoc_D2O;
ADD_IMPORT extern const double ciapws_rhoc_H2O;
ADD_IMPORT extern const double ciapws_rhoc_D2O;

#endif
11 changes: 3 additions & 8 deletions include/iapws_version.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
/**
* @file
* @brief Version
*/

#ifndef iapws_VERSION_H
#define iapws_VERSION_H
extern char* iapws_get_version(void);
#ifndef CIAPWS_VERSION_H
#define CIAPWS_VERSION_H
extern char* ciapws_get_version(void);
#endif

6 changes: 6 additions & 0 deletions src/ciapws.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ciapws
!! Main module for the IAPWS library.
use ciapws__version
use ciapws__r783
use ciapws__g704
end module
46 changes: 23 additions & 23 deletions src/iapws_g704_capi.f90 → src/ciapws_g704.f90
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
module iapws__g704_capi
!! C API for the G704 module.
module ciapws__g704
!! Module for IAPWS G704
use iso_fortran_env
use iso_c_binding
use iso_c_binding, only: c_double, c_int, c_ptr, c_f_pointer, c_char, c_size_t, c_null_char, c_loc
use iapws__g704
implicit none
private

type, bind(C) :: c_char_p
type(c_ptr) :: p
end type
type :: capi_gas_t
type :: cgas_type
character(kind=c_char, len=1), allocatable :: gas(:)
end type
type(capi_gas_t), allocatable, target :: c_gases(:)
type(cgas_type), allocatable, target :: c_gases(:)
type(c_char_p), allocatable, target :: char_pp(:)
character(len=:), allocatable, target :: c_gases_str

public :: iapws_g704_capi_kh, iapws_g704_capi_kd
public :: iapws_g704_capi_ngases
public :: iapws_g704_capi_gases
public :: ciapws_g704_kh, ciapws_g704_kd
public :: ciapws_g704_ngases
public :: ciapws_g704_gases

contains

subroutine iapws_g704_capi_kh(T, gas, heavywater, k, size_gas, size_T)bind(C)
subroutine ciapws_g704_kh(T, gas, heavywater, k, size_gas, size_T)bind(C)
!! Compute the henry constant for a given temperature.
implicit none

Expand Down Expand Up @@ -50,10 +50,10 @@ subroutine iapws_g704_capi_kh(T, gas, heavywater, k, size_gas, size_T)bind(C)
do i=1, size_gas
f_gas(i:i) = c2f_gas(i)
enddo
call iapws_g704_kh(T, f_gas, heavywater, k)
call kh(T, f_gas, heavywater, k)
end subroutine

subroutine iapws_g704_capi_kd(T, gas, heavywater, k, size_gas, size_T)bind(C)
subroutine ciapws_g704_kd(T, gas, heavywater, k, size_gas, size_T)bind(C)
!! Compute the vapor-liquid constant for a given temperature.
implicit none

Expand Down Expand Up @@ -81,10 +81,10 @@ subroutine iapws_g704_capi_kd(T, gas, heavywater, k, size_gas, size_T)bind(C)
do i=1, size_gas
f_gas(i:i) = c2f_gas(i)
enddo
call iapws_g704_kd(T, f_gas, heavywater, k)
call kd(T, f_gas, heavywater, k)
end subroutine

pure function iapws_g704_capi_ngases(heavywater)bind(C)result(n)
pure function ciapws_g704_ngases(heavywater)bind(C)result(n)
!! Returns the number of gases.
implicit none

Expand All @@ -94,24 +94,24 @@ pure function iapws_g704_capi_ngases(heavywater)bind(C)result(n)
integer(c_int) :: n
!! Number of gases.

n = iapws_g704_ngases(heavywater)
n = ngases(heavywater)
end function

function iapws_g704_capi_gases(heavywater)bind(C)result(gases)
function ciapws_g704_gases(heavywater)bind(C)result(list_gases)
!! Returns the list of available gases.
implicit none

! arguments
integer(c_int), intent(in), value :: heavywater
!! Flag if D2O (1) is used or H2O(0).
type(c_ptr) :: gases
type(c_ptr) :: list_gases
!! Available gases.

! variables
integer(int32) :: i, j, ngas, n

type(iapws_g704_gas_t), pointer :: f_gases(:) => null()
f_gases => iapws_g704_gases(heavywater)
type(gas_type), pointer :: f_gases(:) => null()
f_gases => gases(heavywater)
ngas = size(f_gases)

if(allocated(c_gases))then
Expand All @@ -136,22 +136,22 @@ function iapws_g704_capi_gases(heavywater)bind(C)result(gases)
c_gases(i)%gas(n+1) = c_null_char
char_pp(i)%p = c_loc(c_gases(i)%gas)
enddo
gases = c_loc(char_pp)
list_gases = c_loc(char_pp)
end function

function iapws_g704_capi_gases2(heavywater)bind(C)result(gases)
function ciapws_g704_gases2(heavywater)bind(C)result(str_gases)
!! Returns the available gases as a string.
implicit none

! arguments
integer(c_int), intent(in), value :: heavywater
!! Flag if D2O (1) is used or H2O(0).
type(c_ptr) :: gases
type(c_ptr) :: str_gases
!! Available gases.

! variables
character(len=:), pointer :: f_gases_str => null()
f_gases_str => iapws_g704_gases2(heavywater)
f_gases_str => gases2(heavywater)

if(allocated(c_gases_str))then
deallocate(c_gases_str)
Expand All @@ -161,7 +161,7 @@ function iapws_g704_capi_gases2(heavywater)bind(C)result(gases)
c_gases_str = f_gases_str
c_gases_str(len(f_gases_str):len(f_gases_str)) = c_null_char

gases = c_loc(c_gases_str)
str_gases = c_loc(c_gases_str)

end function

Expand Down
24 changes: 24 additions & 0 deletions src/ciapws_r283.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module ciapws__r783
!! Module for IAPWS R283
use iso_c_binding, only: c_double
use iapws__r283
implicit none
private

real(c_double), protected, bind(C) :: ciapws_r283_Tc_H2O = Tc_H2O !! Critical temperature for H2O in K
real(c_double), protected, bind(C) :: ciapws_r283_Tc_D2O = Tc_D2O !! Critical temperature for D2O in K

real(c_double), protected, bind(C) :: ciapws_r283_pc_H2O = pc_H2O !! Critical pressure for H2O in MPa
real(c_double), protected, bind(C) :: ciapws_r283_pc_D2O = pc_D2O !! Critical pressure for D2O in MPa

real(c_double), protected, bind(C) :: ciapws_r283_rhoc_H2O = rhoc_H2O !! Critical density for H2O in kg.m-3
real(c_double), protected, bind(C) :: ciapws_r283_rhoc_D2O = rhoc_D2O !! Critical density for D2O in kg.m-3

public :: ciapws_r283_Tc_H2O, &
ciapws_r283_Tc_D2O, &
ciapws_r283_pc_H2O, &
ciapws_r283_pc_D2O, &
ciapws_r283_rhoc_H2O, &
ciapws_r283_rhoc_D2O

end module
34 changes: 34 additions & 0 deletions src/ciapws_version.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module ciapws__version
!! Version
use iso_c_binding, only: c_null_char, c_ptr, c_loc
use iapws__version
implicit none
private

character(len=:), allocatable, target :: version_c

public :: ciapws_get_version

contains

function ciapws_get_version()bind(c)result(cptr)
!! Get the version.
implicit none

! Returns
type(c_ptr) :: cptr
!! Pointer to version string.

character(len=:), pointer :: fptr
fptr => get_version()

if(allocated(version_c))then
deallocate(version_c)
endif
allocate(character(len=len(fptr)+1) :: version_c)

version_c = fptr // c_null_char
cptr = c_loc(version_c)
end function

end module ciapws__version
2 changes: 1 addition & 1 deletion src/iapws.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module iapws
!! Main module for the IAPWS library.
use iapws__version
use iapws__g704
use iapws__g704_capi
use iapws__r283
use ciapws
end module
Loading

0 comments on commit 7ff5502

Please sign in to comment.