diff --git a/configs/analytical/config.json b/configs/analytical/config.json index 03622f15..2b5917a0 100644 --- a/configs/analytical/config.json +++ b/configs/analytical/config.json @@ -1 +1,6 @@ -{"camp-files": ["species.json", "reactions.json"]} \ No newline at end of file +{ + "camp-files": [ + "species.json", + "reactions.json" + ] +} \ No newline at end of file diff --git a/configs/analytical/reactions.json b/configs/analytical/reactions.json index 3b64908f..e8e2a2c8 100644 --- a/configs/analytical/reactions.json +++ b/configs/analytical/reactions.json @@ -1,32 +1,69 @@ { - "camp-data": - [ + "camp-data": [ { "type": "MECHANISM", "name": "music box interactive configuration", - "reactions": - [ + "reactions": [ { - "type": "USER_DEFINED", - "MUSICA name" : "reaction 2", - "reactants": {"E": {"qty": 1}}, - "products": {"F": {"yield": 1}} + "type": "ARRHENIUS", + "A": 0.004, + "C": 50, + "reactants": { + "A": { + "qty": 1 + } + }, + "products": { + "B": { + "yield": 1 + } + } }, { - "type": "USER_DEFINED", - "MUSICA name" : "reaction 1", - "reactants": {"D": {"qty": 1}}, - "products": {"E": {"yield": 1}} + "type": "ARRHENIUS", + "A": 0.012, + "B": -2, + "C": 75, + "D": 50, + "E": 1.0e-6, + "reactants": { + "B": { + "qty": 1 + } + }, + "products": { + "C": { + "yield": 1 + } + } }, { - "type": "ARRHENIUS", "A": 0.004, "C" : 50, - "reactants": {"A": {"qty": 1}}, - "products": {"B": {"yield": 1}} + "type": "USER_DEFINED", + "MUSICA name": "reaction 1", + "reactants": { + "D": { + "qty": 1 + } + }, + "products": { + "E": { + "yield": 1 + } + } }, { - "type": "ARRHENIUS", "A": 0.012, "B": -2, "C" : 75, "D": 50, "E": 1.0e-6, - "reactants": {"B": {"qty": 1}}, - "products": {"C": {"yield": 1}} + "type": "USER_DEFINED", + "MUSICA name": "reaction 2", + "reactants": { + "E": { + "qty": 1 + } + }, + "products": { + "F": { + "yield": 1 + } + } } ] } diff --git a/configs/analytical/species.json b/configs/analytical/species.json index 63929a19..5500d82d 100644 --- a/configs/analytical/species.json +++ b/configs/analytical/species.json @@ -1,23 +1,28 @@ { - "camp-data": - [ + "camp-data": [ { - "name": "A", "type": "CHEM_SPEC" + "name": "A", + "type": "CHEM_SPEC" }, { - "name": "B", "type": "CHEM_SPEC" + "name": "B", + "type": "CHEM_SPEC" }, { - "name": "C", "type": "CHEM_SPEC" + "name": "C", + "type": "CHEM_SPEC" }, { - "name": "D", "type": "CHEM_SPEC" + "name": "D", + "type": "CHEM_SPEC" }, { - "name": "E", "type": "CHEM_SPEC" + "name": "E", + "type": "CHEM_SPEC" }, { - "name": "F", "type": "CHEM_SPEC" + "name": "F", + "type": "CHEM_SPEC" } ] } \ No newline at end of file diff --git a/docs/source/tutorial/chapter0.rst b/docs/source/tutorial/chapter0.rst index 60993b44..0ff70928 100644 --- a/docs/source/tutorial/chapter0.rst +++ b/docs/source/tutorial/chapter0.rst @@ -1,40 +1,86 @@ Chapter 0 ========= -The MUSICA CMake Package ------------------------- +.. _installing_musica: -The MUSICA library installs with `CMake` ``musica`` and ``musica_fortran`` -packages to facilitate linking -to higher level libraries and host models that have CMake build systems. +Installing MUSICA +----------------- -A minimal ``CMakeLists.txt`` file designed to link the ``musica_fortran`` library -to a Fortran program ``demo_f.f90`` is exhibited below +This tutorial will guide you through the installation and use of MUSICA and +the MUSICA-Fortran interface. The MUSICA library is a C++ library that +provides a set of tools and solvers for the simulation of atmospheric +chemistry and aerosols. The MUSICA-Fortran interface provides a +Fortran API to the MUSICA library. - .. literalinclude:: ../../../fortran/test/tutorial/CMakeLists.txt - :language: cmake +The MUSICA library and the MUSICA-Fortran interface can be installed +together or separately. The MUSICA library is required to build the +MUSICA-Fortran interface. -These `CMake` directives are essentially equivalent to compilation on the command line via +The MUSICA library and the MUSICA-Fortran interface can be installed +using the CMake build system. + + +Local Installation +~~~~~~~~~~~~~~~~~~ + +First, ensure that you have the required dependencies installed. On +Fedora, you can install the required dependencies with the following: .. code-block:: bash - gfortran -o demo_f demo_f.f90 -I/include -L/lib -lmusica-fortran -lmusica -lstdc++ + sudo dnf install -y cmake git gcc-c++ gcc-gfortran netcdf-devel netcdf-fortran-devel -```` is the full path of the MUSICA installation directory, -specified by the option ``CMAKE_INSTALL_PREFIX`` -during the `cmake` configuration process. +On other distributions or operating systems, you may need to install the dependencies +using the package manager for your system. -Common practice is to create a ``build`` subdir (relative to the top level ``CMakeLists.txt`` file, say). +Next, clone the MUSICA repository from GitHub: + +.. code-block:: bash + + git clone https://github.com/NCAR/musica.git + +Next, create a build directory and run CMake: .. code-block:: bash mkdir build cd build + cmake -D CMAKE_INSTALL_PREFIX= -D MUSICA_BUILD_FORTRAN_INTERFACE=ON ../musica -The ``cmake`` could then be invoked with: +where ```` is the directory where you want to install MUSICA. +We use the ``MUSICA_BUILD_FORTRAN_INTERFACE`` option to build the MUSICA-Fortran +interface, which is not built by default. + +Finally, build and install MUSICA: .. code-block:: bash - cmake -DMUSICA_INSTALL_DIR .. - cmake --build . + make + make install + +Docker Installation +~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can build and install MUSICA using Docker. First, ensure +that you have +`Docker Desktop `_ +installed and running on your system. + +Then, clone the MUSICA GitHub repository and use the provided Dockerfile to +build the MUSICA Docker image: + +.. code-block:: bash + + git clone https://github.com/NCAR/musica.git + cd musica + docker build -t musica-fortran -f docker/Dockerfile.fortran-gcc . + docker run -it musica-fortran bash + +You can then perform the remainder of the tutorial inside the Docker container. +The ```` directory used throughout the tutorial will be located at ``/musica/build`` + +Once you are finished, you can exit the container by typing ``exit``. (Note that +the container will be deleted along with any files you created or modified when +you exit.) + diff --git a/docs/source/tutorial/chapter1.rst b/docs/source/tutorial/chapter1.rst index a05c0529..f273dfbe 100644 --- a/docs/source/tutorial/chapter1.rst +++ b/docs/source/tutorial/chapter1.rst @@ -1,36 +1,38 @@ +.. _chapter1: + Chapter 1 ========= First Fortran MUSICA Program ---------------------------- -The MUSICA library can be used within a fortran program. +The MUSICA-Fortran API provides access to the MUSICA library within a fortran program. To get started, let us create a simple program that links to MUSICA and prints the version of MICM. -Here are the contents of the program `demo.f90`: +Save the following code to a file named `demo.F90`: .. literalinclude:: ../../../fortran/test/fetch_content_integration/test_get_micm_version.F90 - :language: f90 + :language: F90 From the ``musica_micm`` module, we only need the function ``get_micm_version``, which returns a derived string type from the ``musica_util`` module, ``string_t``. -The ``string_t`` type will be discussed in more detail in later chapters. +(The ``string_t`` type will be discussed in more detail in later chapters.) To print the version string we just want the fortran character array, -accessed by ``get_char_array``. +accessed by the ``get_char_array`` function. Now, to build this simple program, -invoke the `gfortran` compiler and link to ``libmusica-fortran``, ``libmusica``, +invoke the `gfortran` compiler and link to ``libmusica-fortran``, ``libmusica``, ``yaml-cpp``, and the standard C++ library ``libstdc++``. The full command is .. code-block:: bash - gfortran -o demo demo.f90 -I/include -L/lib -lmusica-fortran -lmusica -lstdc++ + gfortran -o demo demo.F90 -I/include -L/lib64 -lmusica-fortran -lmusica -lstdc++ -lyaml-cpp ```` is the full path of the MUSICA installation directory, specified by the option ``CMAKE_INSTALL_PREFIX`` -during the `cmake` configuration process. -Note the include path allows the linker to find the ``musica_micm.mod`` and ``musica_util.mod`` +during installation (see :ref:`installing_musica`). +Note that the include path allows the linker to find the ``musica_micm.mod`` and ``musica_util.mod`` module definition files. When the `demo` program is run it should display the MICM version: @@ -38,6 +40,36 @@ When the `demo` program is run it should display the MICM version: .. code-block:: bash $ ./demo - MICM version 3.5.0 + MICM version 3.6.0 $ +Building a MUSICA Fortran Program with CMake +-------------------------------------------- + +A minimal ``CMakeLists.txt`` file designed to link the ``musica_fortran`` library +to the ``demo_f.F90`` file described above is exhibited below + + .. literalinclude:: ../../../fortran/test/tutorial/CMakeLists.txt + :language: cmake + +Common practice is to create a ``build`` subdirectory (relative to the top level ``CMakeLists.txt`` file shown above). + +.. code-block:: bash + + mkdir build + cd build + +Then, ``cmake`` can then be invoked with: + +.. code-block:: bash + + cmake -DMUSICA_INSTALL_DIR= .. + make + +Then, the ``demo_f`` executable can be run: + +.. code-block:: bash + + $ ./demo_f + MICM version 3.6.0 + $ diff --git a/docs/source/tutorial/chapter2.rst b/docs/source/tutorial/chapter2.rst index 519ffa20..f208c6ad 100644 --- a/docs/source/tutorial/chapter2.rst +++ b/docs/source/tutorial/chapter2.rst @@ -1,16 +1,25 @@ Chapter 2 ========= -An MICM Box Model Fortran Example ---------------------------------- +An MICM Box Model Example in Fortran +-------------------------------------- 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. +The following three configuration files (``config.json``, ``species.json``, and ``reactions.json``) +should be saved in a subdirectory named ``configs/analytical`` relative directory +from which you plan to call the box model executable. + +(You can find a copy of these files in the MUSICA repository at ``configs/analytical``.) + +The top-level MICM configuration ``config.json`` file +simply lists the configuration files to parse. In this case, these are the +chemical species configuration file ``species.json`` and +the reactions configuration file ``reactions.json``. + +The contents of the ``config.json`` file for this example are: .. literalinclude:: ../../../configs/analytical/config.json :language: json @@ -24,16 +33,21 @@ For this example, we will have a system of three chemical species 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: +and the second reaction with `A` evolving to `B` and using only two reaction parameters. + +We also include two reactions with rate constants that are provided by the host +application at runtime. These types of reactions are useful when outside calculations +are needed to determine the rate constants, such as in the case of photolysis reactions. + +The ``reactions.json`` file for this example should look like this: .. 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/`_ +More information on MICM configurations and reactions can be found in the `MICM documentation +`_ -The Fortran example code is shown below in full: +To create a simple box model, save the following Fortran code to a file named ``micm_box_model.F90``: .. literalinclude:: ../../../fortran/test/fetch_content_integration/test_micm_box_model.F90 :language: f90 @@ -43,23 +57,30 @@ From the ``musica_util`` module we need the Fortran types 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 +so that subdirectory should be created relative to the main program and contain the MICM JSON configuration files, -or otherwise the ``config_path`` should be modified appropriately. +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. +To build the example, follow the instructions in :ref:`chapter1`. + +Assuming you name the executable ``micm_box_model``, you can run the program as follows: + .. 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 + $ ./micm_box_model + Creating MICM solver... + Species Name:A, Index: 1 + Species Name:B, Index: 2 + Species Name:C, Index: 5 + Species Name:D, Index: 3 + Species Name:E, Index: 4 + Species Name:F, Index: 6 + Solving starts... + After solving, concentrations 0.38236272259073301 1.4676807523204496 0.67030703490468713 1.1155750798779909 1.1499565250888166 1.2141178852173222 $ diff --git a/fortran/test/fetch_content_integration/test_get_micm_version.F90 b/fortran/test/fetch_content_integration/test_get_micm_version.F90 index 98e30f3e..a4696d07 100644 --- a/fortran/test/fetch_content_integration/test_get_micm_version.F90 +++ b/fortran/test/fetch_content_integration/test_get_micm_version.F90 @@ -1,8 +1,12 @@ program demo + use musica_util, only: string_t use musica_micm, only: get_micm_version implicit none + type(string_t) :: micm_version + micm_version = get_micm_version() print *, "MICM version ", micm_version%get_char_array() + end program demo diff --git a/fortran/test/tutorial/CMakeLists.txt b/fortran/test/tutorial/CMakeLists.txt index aae019eb..40ea5642 100644 --- a/fortran/test/tutorial/CMakeLists.txt +++ b/fortran/test/tutorial/CMakeLists.txt @@ -6,18 +6,14 @@ project( LANGUAGES CXX C Fortran ) -# mkdir build -# cd build -# cmake -DMUSICA_INSTALL_DIR= .. - set(MUSICA_INCLUDE_DIR "${MUSICA_INSTALL_DIR}/include") -set(MUSICA_LIB_DIR "${MUSICA_INSTALL_DIR}/lib") +set(MUSICA_LIB_DIR "${MUSICA_INSTALL_DIR}/lib64") message(STATUS "${MUSICA_INCLUDE_DIR}") message(STATUS "${MUSICA_LIB_DIR}") -add_executable(demo_f demo.f90) +add_executable(demo_f demo.F90) target_include_directories(demo_f PUBLIC ${MUSICA_INCLUDE_DIR}) target_link_directories(demo_f PUBLIC ${MUSICA_LIB_DIR}) -target_link_libraries(demo_f musica-fortran musica stdc++) +target_link_libraries(demo_f musica-fortran musica stdc++ yaml-cpp) diff --git a/fortran/test/tutorial/demo.f90 b/fortran/test/tutorial/demo.F90 similarity index 97% rename from fortran/test/tutorial/demo.f90 rename to fortran/test/tutorial/demo.F90 index 299411bc..5a506cec 100644 --- a/fortran/test/tutorial/demo.f90 +++ b/fortran/test/tutorial/demo.F90 @@ -1,8 +1,12 @@ program demo + use musica_util, only: string_t use musica_micm, only: get_micm_version implicit none + type(string_t) :: micm_version + micm_version = get_micm_version() print *, "MICM version ", micm_version%get_char_array() + end program demo diff --git a/fortran/test/unit/CMakeLists.txt b/fortran/test/unit/CMakeLists.txt index bf88b83b..f7e09f19 100644 --- a/fortran/test/unit/CMakeLists.txt +++ b/fortran/test/unit/CMakeLists.txt @@ -4,7 +4,7 @@ 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) - create_standard_test_fortran(NAME demo_fortran SOURCES ../tutorial/demo.f90) + create_standard_test_fortran(NAME demo_fortran SOURCES ../tutorial/demo.F90) endif() if (MUSICA_ENABLE_TUVX)