Skip to content

Commit

Permalink
81 supply custom rate constants to fortran (#82)
Browse files Browse the repository at this point in the history
* passed mapping properly

* using the user defined reaction rates

* changing branch

* correcting usage

* adding correct config copy path

* private sources

* better naming
  • Loading branch information
K20shores authored Apr 5, 2024
1 parent dec894e commit 2ffaaa0
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 61 deletions.
2 changes: 1 addition & 1 deletion docker/Dockerfile.fortran-gcc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ RUN cd musica/fortran/test/fetch_content_integration \
-D CMAKE_BUILD_TYPE=Debug \
&& make

RUN cp -r /musica/configs/chapman musica/fortran/test/fetch_content_integration/build
RUN cp -r /musica/configs musica/fortran/test/fetch_content_integration/build

WORKDIR musica/fortran/test/fetch_content_integration/build
2 changes: 1 addition & 1 deletion docker/Dockerfile.fortran-intel
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ RUN cd musica/fortran/test/fetch_content_integration \
-D CMAKE_BUILD_TYPE=Release \
&& make

RUN cp -r /musica/configs/chapman musica/fortran/test/fetch_content_integration/build
RUN cp -r /musica/configs musica/fortran/test/fetch_content_integration/build

WORKDIR musica/fortran/test/fetch_content_integration/build
2 changes: 1 addition & 1 deletion docker/Dockerfile.fortran-nvhpc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ RUN cd musica/fortran/test/fetch_content_integration \
-D CMAKE_BUILD_TYPE=Release \
&& make

RUN cp -r /musica/configs/chapman musica/fortran/test/fetch_content_integration/build
RUN cp -r /musica/configs musica/fortran/test/fetch_content_integration/build

WORKDIR musica/fortran/test/fetch_content_integration/build
2 changes: 1 addition & 1 deletion fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ target_link_libraries(musica-fortran
)

target_sources(musica-fortran
PUBLIC
PRIVATE
micm_core.F90
)

Expand Down
31 changes: 18 additions & 13 deletions fortran/micm_core.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ module micm_core
use iso_c_binding, only: c_ptr, c_char, c_int, c_double, c_null_char, c_size_t, c_f_pointer
implicit none

public :: micm_t
public :: micm_t, mapping_t
private

type, bind(c) :: Mapping
type, bind(c) :: mapping_t
character(kind=c_char, len=1) :: name(256)
integer(c_size_t) :: index
end type Mapping
integer(c_size_t) :: string_length
end type mapping_t

interface
function create_micm_c(config_path, error_code) bind(C, name="create_micm")
Expand All @@ -24,14 +25,17 @@ subroutine delete_micm_c(micm) bind(C, name="delete_micm")
type(c_ptr), intent(in) :: micm
end subroutine delete_micm_c

subroutine micm_solve_c(micm, time_step, temperature, pressure, num_concentrations, concentrations) bind(C, name="micm_solve")
subroutine micm_solve_c(micm, time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates) bind(C, name="micm_solve")
import c_ptr, c_double, c_int
type(c_ptr), value, intent(in) :: micm
real(kind=c_double), value, intent(in) :: time_step
real(kind=c_double), value, intent(in) :: temperature
real(kind=c_double), value, intent(in) :: pressure
integer(kind=c_int), value, intent(in) :: num_concentrations
real(kind=c_double), intent(inout) :: concentrations(num_concentrations)
integer(kind=c_int), value, intent(in) :: num_user_defined_reaction_rates
real(kind=c_double), intent(inout) :: user_defined_reaction_rates(num_user_defined_reaction_rates)
end subroutine micm_solve_c

function get_species_ordering(micm, array_size) bind(c, name="get_species_ordering")
Expand All @@ -50,8 +54,8 @@ end function get_user_defined_reaction_rates_ordering
end interface

type :: micm_t
type(Mapping), pointer :: species_ordering(:), reaction_rates_ordering(:)
integer(kind=c_size_t) :: species_ordering_length, reaction_rates_ordering_length
type(mapping_t), pointer :: species_ordering(:), user_defined_reaction_rates(:)
integer(kind=c_size_t) :: species_ordering_length, user_defined_reaction_rates_length
type(c_ptr), private :: ptr
contains
! Solve the chemical system
Expand All @@ -76,7 +80,6 @@ function constructor(config_path, errcode) result( this )

allocate( this )

print *, "Config Path:", config_path
n = len_trim(config_path)
do i = 1, n
c_config_path(i) = config_path(i:i)
Expand All @@ -92,21 +95,23 @@ function constructor(config_path, errcode) result( this )
mappings_ptr = get_species_ordering(this%ptr, this%species_ordering_length)
call c_f_pointer(mappings_ptr, this%species_ordering, [this%species_ordering_length])

! this%reaction_rates_ordering = get_user_defined_reaction_rates_ordering(this%ptr, this%reaction_rates_ordering_length)

! do i = 1, this%reaction_rates_ordering_length
! print *, "Reaction Rate Name:", this%reaction_rates_ordering(i)%name, ", Index:", this%reaction_rates_ordering(i)%index
! end do
mappings_ptr = get_user_defined_reaction_rates_ordering(this%ptr, this%user_defined_reaction_rates_length)
call c_f_pointer(mappings_ptr, this%user_defined_reaction_rates, [this%user_defined_reaction_rates_length])
end function constructor

subroutine solve(this, time_step, temperature, pressure, num_concentrations, concentrations)
subroutine solve(this, time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates)
class(micm_t) :: this
real(c_double), intent(in) :: time_step
real(c_double), intent(in) :: temperature
real(c_double), intent(in) :: pressure
integer(c_int), intent(in) :: num_concentrations
real(c_double), intent(inout) :: concentrations(*)
call micm_solve_c(this%ptr, time_step, temperature, pressure, num_concentrations, concentrations)
integer(c_int), intent(in) :: num_user_defined_reaction_rates
real(c_double), intent(inout) :: user_defined_reaction_rates(*)
call micm_solve_c(this%ptr, time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates)
end subroutine solve

subroutine finalize(this)
Expand Down
Binary file added fortran/micm_core.mod
Binary file not shown.
31 changes: 23 additions & 8 deletions fortran/test/fetch_content_integration/test_micm_fort_api.F90
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
program test_micm_fort_api
use iso_c_binding
use micm_core, only: micm_t
use micm_core, only: micm_t, mapping_t

implicit none

type(micm_t), pointer :: micm
real(c_double) :: time_step
real(c_double) :: temperature
real(c_double) :: pressure
integer(c_int) :: num_concentrations
real(c_double), dimension(5) :: concentrations
integer :: errcode
character(len=7) :: config_path
integer(c_int) :: num_concentrations, num_user_defined_reaction_rates
real(c_double), dimension(5) :: concentrations
real(c_double), dimension(3) :: user_defined_reaction_rates
integer :: errcode, i
character(len=256) :: config_path
type(mapping_t) :: the_mapping

time_step = 200
temperature = 272.5
pressure = 101253.3
pressure = 101253.4
num_concentrations = 5
concentrations = (/ 0.75, 0.4, 0.8, 0.01, 0.02 /)
config_path = "chapman"
config_path = "configs/chapman"
num_user_defined_reaction_rates = 3
user_defined_reaction_rates = (/ 0.1, 0.2, 0.3 /)


write(*,*) "[test micm fort api] Creating MICM solver..."
micm => micm_t(config_path, errcode)

do i = 1, micm%species_ordering_length
the_mapping = micm%species_ordering(i)
print *, "Species Name:", the_mapping%name(:the_mapping%string_length), ", Index:", the_mapping%index
end do
do i = 1, micm%user_defined_reaction_rates_length
the_mapping = micm%user_defined_reaction_rates(i)
print *, "User Defined Reaction Rate Name:", the_mapping%name(:the_mapping%string_length), ", Index:", the_mapping%index
end do

if (errcode /= 0) then
write(*,*) "[test micm fort api] Failed in creating solver."
stop 3
Expand All @@ -31,7 +45,8 @@ program test_micm_fort_api
write(*,*) "[test micm fort api] Initial concentrations", concentrations

write(*,*) "[test micm fort api] Solving starts..."
call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations)
call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates)

write(*,*) "[test micm fort api] After solving, concentrations", concentrations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,9 @@ subroutine test_micm_fort_api_invalid()
implicit none

type(micm_t), pointer :: micm
real(c_double) :: time_step
real(c_double) :: temperature
real(c_double) :: pressure
integer(c_int) :: num_concentrations
real(c_double), dimension(5) :: concentrations
integer :: errcode
character(len=7) :: config_path

time_step = 200
temperature = 272.5
pressure = 101253.3
num_concentrations = 5
concentrations = (/ 0.75, 0.4, 0.8, 0.01, 0.02 /)
config_path = "invalid_config"

write(*,*) "[test micm fort api] Creating MICM solver..."
Expand Down
29 changes: 22 additions & 7 deletions fortran/test/unit/test_musica_fortran_interface.F90
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
program test_micm_fort_api
use iso_c_binding
use micm_core, only: micm_t
use micm_core, only: micm_t, mapping_t

implicit none

type(micm_t), pointer :: micm
real(c_double) :: time_step
real(c_double) :: temperature
real(c_double) :: pressure
integer(c_int) :: num_concentrations
real(c_double), dimension(5) :: concentrations
integer :: errcode
character(len=7) :: config_path
integer(c_int) :: num_concentrations, num_user_defined_reaction_rates
real(c_double), dimension(5) :: concentrations
real(c_double), dimension(3) :: user_defined_reaction_rates
integer :: errcode, i
character(len=256) :: config_path
type(mapping_t) :: the_mapping

time_step = 200
temperature = 272.5
pressure = 101253.3
pressure = 101253.4
num_concentrations = 5
concentrations = (/ 0.75, 0.4, 0.8, 0.01, 0.02 /)
config_path = "configs/chapman"
num_user_defined_reaction_rates = 3
user_defined_reaction_rates = (/ 0.1, 0.2, 0.3 /)


write(*,*) "[test micm fort api] Creating MICM solver..."
micm => micm_t(config_path, errcode)

do i = 1, micm%species_ordering_length
the_mapping = micm%species_ordering(i)
print *, "Species Name:", the_mapping%name(:the_mapping%string_length), ", Index:", the_mapping%index
end do
do i = 1, micm%user_defined_reaction_rates_length
the_mapping = micm%user_defined_reaction_rates(i)
print *, "User Defined Reaction Rate Name:", the_mapping%name(:the_mapping%string_length), ", Index:", the_mapping%index
end do

if (errcode /= 0) then
write(*,*) "[test micm fort api] Failed in creating solver."
stop 3
Expand All @@ -31,7 +45,8 @@ program test_micm_fort_api
write(*,*) "[test micm fort api] Initial concentrations", concentrations

write(*,*) "[test micm fort api] Solving starts..."
call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations)
call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates)

write(*,*) "[test micm fort api] After solving, concentrations", concentrations

Expand Down
9 changes: 2 additions & 7 deletions include/musica/micm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ class MICM;

struct Mapping
{
char *name;
char name[256];
size_t index;
size_t string_length;
};

#ifdef __cplusplus
Expand All @@ -39,12 +40,6 @@ extern "C"
class MICM
{
public:
/// @brief Constructor
MICM();

/// @brief Destructor
~MICM();

/// @brief Create a solver by reading and parsing configuration file
/// @param config_path Path to configuration file or directory containing configuration file
/// @return 0 on success, 1 on failure in parsing configuration file
Expand Down
18 changes: 6 additions & 12 deletions src/micm/micm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,22 @@ void micm_solve(MICM *micm, double time_step, double temperature, double pressur
Mapping *get_species_ordering(MICM *micm, size_t *array_size)
{
auto map = micm->get_species_ordering();
Mapping *reactionRates = new Mapping[map.size()];
Mapping *species_ordering = new Mapping[map.size()];

// Copy data from the map to the array of structs
size_t i = 0;
for (const auto &entry : map)
{
reactionRates[i].name = new char[entry.first.size() + 1]; // +1 for null terminator
std::strcpy(reactionRates[i].name, entry.first.c_str());
reactionRates[i].index = entry.second;
std::strcpy(species_ordering[i].name, entry.first.c_str());
species_ordering[i].index = entry.second;
species_ordering[i].string_length = entry.first.size();
++i;
}

// Set the size of the array
*array_size = map.size();

return reactionRates;
return species_ordering;
}

Mapping *get_user_defined_reaction_rates_ordering(MICM *micm, size_t *array_size)
Expand All @@ -67,9 +67,9 @@ Mapping *get_user_defined_reaction_rates_ordering(MICM *micm, size_t *array_size
size_t i = 0;
for (const auto &entry : map)
{
reactionRates[i].name = new char[entry.first.size() + 1]; // +1 for null terminator
std::strcpy(reactionRates[i].name, entry.first.c_str());
reactionRates[i].index = entry.second;
reactionRates[i].string_length = entry.first.size();
++i;
}

Expand All @@ -79,12 +79,6 @@ Mapping *get_user_defined_reaction_rates_ordering(MICM *micm, size_t *array_size
return reactionRates;
}

MICM::MICM() : solver_(nullptr) {}

MICM::~MICM()
{
}

int MICM::create_solver(const std::string &config_path)
{
int parsing_status = 0; // 0 on success, 1 on failure
Expand Down

0 comments on commit 2ffaaa0

Please sign in to comment.