Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUSICA Tutorial Chapter 2 #141

Merged
merged 23 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions docs/source/tutorial/chapter2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Chapter 2
=========

An MICM Box Model Fortran Example
---------------------------------

In this next MUSICA Fortran example,
we will setup a MICM solver, starting with a set of MICM configuration files,
and run the solver for a single integration time step.

The MICM configuration is specified in a top-level ``config.json`` file,
which simply lists the chemical species configuration file followed by
the reactions configuration file.

.. literalinclude:: ../../../configs/analytical/config.json
:language: json

For this example, we will have a system of three chemical species
`A`, `B`, and `C`, defined in the JSON file ``species.json`` as follows:

.. literalinclude:: ../../../configs/analytical/species.json
:language: json

The ``reactions.json`` specifies a mechanism, or a set of reactions for the system.
Here, we will introduce two Arrhenius type reactions, the first
with `B` evolving to `C`, and specifying all five reaction parameters,
and the second reaction with `A` evolving to `B` and using only two reaction parameters.
The mechanism configuration might then be set up as:

.. literalinclude:: ../../../configs/analytical/reactions.json
:language: json

More information on MICM configurations and reactions can be found in the MICM documentation
at `https://ncar.github.io/micm/user_guide/`_

The Fortran example code is shown below in full:

.. literalinclude:: ../../../fortran/test/fetch_content_integration/test_micm_box_model.F90
:language: f90

From the ``musica_util`` module we need the Fortran types
``error_t``, ``string_t``, and ``mapping_t``.
A pointer to a ``musica_micm::micm_t`` will serve as the interface to the MICM solver
(in the example the pointer name is ``micm``).
Note that the ``config_path`` in the code sample has been set to ``configs/analytical``,
so that subdir should be created relative to the main program and contain
the MICM JSON configuration files,
or otherwise the ``config_path`` should be modified appropriately.
The initial species concentrations are initialized in the ``concentrations`` array,
which is an argument to the MICM solver.

Finally, a single time step solution is obtained through a call to ``micm%solve``,
after which the updated concentrations may be displayed.

.. code-block:: bash

$ ./test_micm_box_model
Creating MICM solver...
Species Name:A, Index: 1
Species Name:B, Index: 2
Species Name:C, Index: 3
Solving starts...
After solving, concentrations 0.38 1.61E-009 2.62
$

1 change: 1 addition & 0 deletions docs/source/tutorial/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Tutorial
:caption: Contents:

chapter1.rst
chapter2.rst
17 changes: 17 additions & 0 deletions fortran/test/fetch_content_integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enable_testing()
if (MUSICA_ENABLE_MICM)
add_executable(test_micm_fortran_api test_micm_api.F90)
add_executable(test_get_micm_version test_get_micm_version.F90)
add_executable(test_micm_box_model test_micm_box_model.F90)

target_link_libraries(test_micm_fortran_api
PRIVATE
Expand Down Expand Up @@ -68,6 +69,22 @@ if (MUSICA_ENABLE_MICM)
COMMAND $<TARGET_FILE:test_get_micm_version>
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)

target_link_libraries(test_micm_box_model
PRIVATE
musica::musica-fortran
)
Comment on lines +72 to +76
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might need to add this line:

add_exectuable(test_micm_box_model test_micm_box_model.F90)

unless I'm just missing where this is


set_target_properties(test_micm_box_model
PROPERTIES
LINKER_LANGUAGE Fortran
)

add_test(
NAME test_micm_box_model
COMMAND $<TARGET_FILE:test_micm_box_model>
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()

# API Test
Expand Down
69 changes: 69 additions & 0 deletions fortran/test/fetch_content_integration/test_micm_box_model.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
program test_micm_box_model

use, intrinsic :: iso_c_binding
use, intrinsic :: ieee_arithmetic

use musica_util, only: error_t, string_t, mapping_t
use musica_micm, only: micm_t, solver_stats_t

implicit none

call box_model()

contains

subroutine box_model()

character(len=256) :: config_path

real(c_double), parameter :: GAS_CONSTANT = 8.31446261815324_c_double ! J mol-1 K-1

real(c_double) :: time_step
real(c_double) :: temperature
real(c_double) :: pressure
real(c_double) :: air_density

integer(c_int) :: num_concentrations = 3
real(c_double), dimension(3) :: concentrations

integer(c_int) :: num_user_defined_reaction_rates = 0
real(c_double), dimension(:), allocatable :: user_defined_reaction_rates

type(string_t) :: solver_state
type(solver_stats_t) :: solver_stats
type(error_t) :: error

type(micm_t), pointer :: micm

integer :: i

config_path = "configs/analytical"

time_step = 200
temperature = 273.0
pressure = 1.0e5
air_density = pressure / (GAS_CONSTANT * temperature)

concentrations = (/ 1.0, 1.0, 1.0 /)

write(*,*) "Creating MICM solver..."
micm => micm_t(config_path, error)

do i = 1, size( micm%species_ordering )
associate(the_mapping => micm%species_ordering(i))
print *, "Species Name:", the_mapping%name(), ", Index:", the_mapping%index()
end associate
end do

write(*,*) "Solving starts..."
! call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations, &
! num_user_defined_reaction_rates, user_defined_reaction_rates, error)
call micm%solve(time_step, temperature, pressure, air_density, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates, solver_state, solver_stats, error)
write(*,*) "After solving, concentrations", concentrations

deallocate( micm )

end subroutine box_model

end program test_micm_box_model
1 change: 1 addition & 0 deletions fortran/test/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ create_standard_test_fortran(NAME fortran_util SOURCES util.F90)
if (MUSICA_ENABLE_MICM)
create_standard_test_fortran(NAME micm_fortran_api SOURCES ../fetch_content_integration/test_micm_api.F90)
create_standard_test_fortran(NAME get_micm_version SOURCES ../fetch_content_integration/test_get_micm_version.F90)
create_standard_test_fortran(NAME micm_box_model SOURCES ../fetch_content_integration/test_micm_box_model.F90)
endif()

if (MUSICA_ENABLE_TUVX)
Expand Down
1 change: 1 addition & 0 deletions src/micm/micm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// creating and deleting MICM instances, creating solvers, and solving the model.
#include <musica/micm.hpp>

#include <micm/version.hpp>
#include <micm/solver/rosenbrock_solver_parameters.hpp>
#include <micm/solver/solver_builder.hpp>
#include <micm/system/species.hpp>
Expand Down
Loading