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

Register species from MICM #93

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: build
on: [pull_request,workflow_dispatch]

jobs:
test_micm_api:
test_musica_api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
133 changes: 87 additions & 46 deletions musica/micm/micm.F90
Original file line number Diff line number Diff line change
@@ -1,55 +1,98 @@
module micm
module musica_ccpp_micm
use iso_c_binding

! Note: "micm_core" is included in an external pre-built MICM library that the host
! model is responsible for linking to during compilation
use micm_core, only: micm_t
use ccpp_kinds, only: kind_phys
use musica_micm, only: micm_t
use musica_ccpp_util, only: has_error_occurred
use ccpp_kinds, only: rk =>kind_phys
boulderdaze marked this conversation as resolved.
Show resolved Hide resolved
use musica_namelist, only: filename_of_micm_configuration
nusbaume marked this conversation as resolved.
Show resolved Hide resolved

implicit none
private

public :: micm_init, micm_run, micm_final
private :: convert_to_mol_per_cubic_meter, convert_to_mass_mixing_ratio
public :: micm_register, micm_init, micm_run, micm_final

type(micm_t), pointer :: micm_obj
type(micm_t), pointer :: micm => null( )

contains

!> \section arg_table_micm_init Argument Table
!! \htmlinclude micm_init.html
subroutine micm_init(config_path, iulog, errcode, errmsg)
character(len=*), intent(in) :: config_path
integer, intent(in) :: iulog
!> Register MICM constituents with the CCPP
subroutine micm_register(constituents, errcode, errmsg)
use ccpp_constituent_prop_mod, only: ccpp_constituent_properties_t
use musica_util, only: error_t, mapping_t
type(ccpp_constituent_properties_t), allocatable, intent(out) :: constituents(:)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

type(error_t) :: error
type(mapping_t) :: mapping
real(kind=rk) :: molar_mass
logical :: is_advected
integer :: i

errcode = 0
errmsg = ''

micm_obj => micm_t(config_path, errcode)
micm => micm_t(filename_of_micm_configuration, error)
if (has_error_occurred(error, errcode, errmsg)) return

allocate(constituents(size(micm%species_ordering)), stat=errcode)
if (errcode /= 0) then
errmsg = "[fatal] [micm] Failed to create MICM solver. Parsing configuration failed. &
Please look over at MICM log file for further information."
errmsg = "[MUSICA Error] Failed to allocate memory for constituents."
return
endif
end if

do i = 1, size(micm%species_ordering)
associate( map => micm%species_ordering(i) )
molar_mass = micm%get_species_property_double(map%name(), &
"molecular weight [kg mol-1]", &
error)
if (has_error_occurred(error, errcode, errmsg)) return
is_advected = micm%get_species_property_bool(map%name(), &
"__is advected", &
error)
if (has_error_occurred(error, errcode, errmsg)) return

call constituents(map%index())%instantiate( &
std_name = map%name(), &
long_name = map%name(), &
units = 'kg kg-1', &
vertical_dim = 'vertical_layer_dimension', &
default_value = 0.0_rk, &
min_value = 0.0_rk, &
molar_mass = molar_mass, &
advected = is_advected, &
errcode = errcode, &
errmsg = errmsg)
if (errcode /= 0) return
end associate
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
end do

end subroutine micm_register

!> Intitialize MICM
subroutine micm_init(errcode, errmsg)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

write(iulog,*) "[info] [micm] Created MICM solver."
errcode = 0
errmsg = ''

end subroutine micm_init

!> \section arg_table_micm_run Argument Table
!! \htmlinclude micm_run.html
!> Solve chemistry at the current time step
subroutine micm_run(time_step, temperature, pressure, dry_air_density, constituent_props, &
constituents, iulog, errcode, errmsg)
use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t
use musica_util, only: error_t
nusbaume marked this conversation as resolved.
Show resolved Hide resolved

real(kind_phys), intent(in) :: time_step ! s
real(kind_phys), intent(in) :: temperature(:,:) ! K
real(kind_phys), intent(in) :: pressure(:,:) ! Pa
real(kind_phys), intent(in) :: dry_air_density(:,:) ! kg m-3
real(rk), intent(in) :: time_step ! s
real(rk), intent(in) :: temperature(:,:) ! K
real(rk), intent(in) :: pressure(:,:) ! Pa
real(rk), intent(in) :: dry_air_density(:,:) ! kg m-3
type(ccpp_constituent_prop_ptr_t), intent(in) :: constituent_props(:)
real(kind_phys), intent(inout) :: constituents(:,:,:) ! kg kg-1
real(rk), intent(inout) :: constituents(:,:,:) ! kg kg-1
integer, intent(in) :: iulog
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg
Expand All @@ -63,8 +106,12 @@ subroutine micm_run(time_step, temperature, pressure, dry_air_density, constitue
real(c_double), dimension(size(constituents, dim=1), &
size(constituents, dim=2), &
size(constituents, dim=3)) :: c_constituents
real(c_double), dimension(size(constituents, dim=1), &
size(constituents, dim=3), &
0) :: c_rate_params
nusbaume marked this conversation as resolved.
Show resolved Hide resolved

real(kind_phys), dimension(size(constituents, dim=3)) :: molar_mass_arr ! kg mol-1
real(rk), dimension(size(constituents, dim=3)) :: molar_mass_arr ! kg mol-1
type(error_t) :: error

integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_elem
Expand Down Expand Up @@ -104,48 +151,42 @@ subroutine micm_run(time_step, temperature, pressure, dry_air_density, constitue
c_pressure = real(pressure, c_double)
c_constituents = real(constituents, c_double)

write(iulog,*) "[info] [micm] Running MICM solver..."

do i_column = 1, num_columns
do i_layer = 1, num_layers
call micm_obj%solve(c_temperature(i_column, i_layer), c_pressure(i_column, i_layer), &
c_time_step, num_constituents, c_constituents(i_column, i_layer, :))
call micm%solve(c_temperature(i_column, i_layer), c_pressure(i_column, i_layer), &
c_time_step, num_constituents, c_constituents(i_column, i_layer, :), &
0, c_rate_params(i_column, i_layer, :), error)
if (has_error_occurred(error, errcode, errmsg)) return
end do
end do

write(iulog,*) "[info] [micm] MICM solver has finished."

constituents = real(c_constituents, kind_phys)
constituents = real(c_constituents, rk)

! Convert MICM unit back to CAM-SIMA unit (mol m-3 -> kg kg-1)
call convert_to_mass_mixing_ratio(dry_air_density, molar_mass_arr, constituents)

end subroutine micm_run

!> \section arg_table_micm_final Argument Table
!! \htmlinclude micm_final.html
subroutine micm_final(iulog, errcode, errmsg)
integer, intent(in) :: iulog
!> Finalize MICM
subroutine micm_final(errcode, errmsg)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

errcode = 0
errmsg = ''

write(iulog,*) "[debug] [micm] Deallocating MICM object..."

end subroutine micm_final

! Convert CAM-SIMA unit to MICM unit (kg kg-1 -> mol m-3)
subroutine convert_to_mol_per_cubic_meter(dry_air_density, molar_mass_arr, constituents)
real(kind_phys), intent(in) :: dry_air_density(:,:) ! kg m-3
real(kind_phys), intent(in) :: molar_mass_arr(:) ! kg mol-1
real(kind_phys), intent(inout) :: constituents(:,:,:) ! in: kg kg-1 | out: mol m-3
real(rk), intent(in) :: dry_air_density(:,:) ! kg m-3
real(rk), intent(in) :: molar_mass_arr(:) ! kg mol-1
real(rk), intent(inout) :: constituents(:,:,:) ! in: kg kg-1 | out: mol m-3

integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_elem

real(kind_phys) :: val
real(rk) :: val

num_columns = size(constituents, dim=1)
num_layers = size(constituents, dim=2)
Expand All @@ -165,14 +206,14 @@ end subroutine convert_to_mol_per_cubic_meter

! Convert MICM unit to CAM-SIMA unit (mol m-3 -> kg kg-1)
subroutine convert_to_mass_mixing_ratio(dry_air_density, molar_mass_arr, constituents)
real(kind_phys), intent(in) :: dry_air_density(:,:) ! kg m-3
real(kind_phys), intent(in) :: molar_mass_arr(:) ! kg mol-1
real(kind_phys), intent(inout) :: constituents(:,:,:) ! in: mol m-3 | out: kg kg-1
real(rk), intent(in) :: dry_air_density(:,:) ! kg m-3
real(rk), intent(in) :: molar_mass_arr(:) ! kg mol-1
real(rk), intent(inout) :: constituents(:,:,:) ! in: mol m-3 | out: kg kg-1

integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_elem

real(kind_phys) :: val
real(rk) :: val

num_columns = size(constituents, dim=1)
num_layers = size(constituents, dim=2)
Expand All @@ -190,4 +231,4 @@ subroutine convert_to_mass_mixing_ratio(dry_air_density, molar_mass_arr, constit

end subroutine convert_to_mass_mixing_ratio

end module micm
end module musica_ccpp_micm
63 changes: 63 additions & 0 deletions musica/musica.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
!> Top-level wrapper for MUSICA chemistry components
module musica_ccpp
use musica_ccpp_micm, only : micm_register, micm_init, micm_run, micm_final

implicit none
private

public :: musica_register, musica_init, musica_run, musica_final

contains

!> \section arg_table_musica_register Argument Table
!! \htmlinclude musica_register.html
subroutine musica_register(constituents, errcode, errmsg)
use ccpp_constituent_prop_mod, only : ccpp_constituent_properties_t
nusbaume marked this conversation as resolved.
Show resolved Hide resolved
type(ccpp_constituent_properties_t), allocatable, intent(out) :: constituents(:)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

call micm_register(constituents, errcode, errmsg)
end subroutine musica_register

!> \section arg_table_musica_init Argument Table
!! \htmlinclude musica_init.html
subroutine musica_init(errcode, errmsg)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

call micm_init(errcode, errmsg)
end subroutine musica_init

!> \section arg_table_musica_run Argument Table
!! \htmlinclude musica_run.html
subroutine musica_run(time_step, temperature, pressure, dry_air_density, constituent_props, &
constituents, iulog, errcode, errmsg)
use ccpp_kinds, only: kind_phys
use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t

real(kind_phys), intent(in) :: time_step ! s
real(kind_phys), intent(in) :: temperature(:,:) ! K
real(kind_phys), intent(in) :: pressure(:,:) ! Pa
real(kind_phys), intent(in) :: dry_air_density(:,:) ! kg m-3
type(ccpp_constituent_prop_ptr_t), intent(in) :: constituent_props(:)
real(kind_phys), intent(inout) :: constituents(:,:,:) ! kg kg-1
integer, intent(in) :: iulog
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

call micm_run(time_step, temperature, pressure, dry_air_density, constituent_props, &
constituents, iulog, errcode, errmsg)
nusbaume marked this conversation as resolved.
Show resolved Hide resolved

end subroutine musica_run

!> \section arg_table_musica_final Argument Table
!! \htmlinclude musica_final.html
subroutine musica_final(errcode, errmsg)
integer, intent(out) :: errcode
character(len=512), intent(out) :: errmsg

call micm_final(errcode, errmsg)
end subroutine musica_final

end module musica_ccpp
27 changes: 5 additions & 22 deletions musica/micm/micm.meta → musica/musica.meta
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
[ccpp-table-properties]
name = micm
name = musica
type = scheme
dynamic_constituent_routine = musica_register
Comment on lines 1 to +4
Copy link
Collaborator

Choose a reason for hiding this comment

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

@peverwhee might know this better than I do, but I think you'll need a dependencies line here to ensure that micm is properly linked to the musica interface in the CCPP framework:

dependencies = micm/micm.F90,util.F90

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe @mattldawson has added the dependencies line in his sandbox, but CAM-SIMA doesn't currently do anything with the dependencies (i.e. grab them during the build)

I've added an agenda item for tuesday's meeting.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for letting me know @peverwhee! Happy to discuss this Tuesday, although I am guessing if the framework is able to provide the list of dependency files at code generation time it will probably be trivial (e.g. a handful of new lines) to get the correct info into CAM-SIMA for successful building/linking.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

After our discussion in the CAM-SIMA development meeting, I believe the plan is to wait until the constituents PR for the CCPP-framework is merged in (NCAR/ccpp-framework#549) and then create an issue to update the framework to provide absolute paths for dependencies in the ccpp_datatable.xml file. This will allow CAM-SIMA to include the dependencies in the build with minor modification. @nusbaume @peverwhee - is this correct?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep, that sounds like the correct plan to me!


[ccpp-arg-table]
name = micm_init
name = musica_init
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
type = scheme
[ config_path ]
standard_name = filename_of_micm_configuration
units = none
type = character | kind = len=*
dimensions = ()
intent = in
[ iulog ]
standard_name = log_output_unit
units = 1
type = integer
dimensions = ()
intent = in
[ errcode ]
standard_name = ccpp_error_code
units = 1
Expand All @@ -31,7 +20,7 @@
intent = out

[ccpp-arg-table]
name = micm_run
name = musica_run
type = scheme
[ time_step ]
standard_name = timestep_for_physics
Expand Down Expand Up @@ -89,14 +78,8 @@
intent = out

[ccpp-arg-table]
name = micm_final
name = musica_final
type = scheme
[ iulog ]
standard_name = log_output_unit
units = 1
type = integer
dimensions = ()
intent = in
[ errcode ]
standard_name = ccpp_error_code
units = 1
Expand Down
4 changes: 2 additions & 2 deletions musica/micm/micm_namelist.xml → musica/musica_namelist.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@
units
This is the CCPP unit specification of the variable (e.g., m s-1).
-->
<!-- MICM configuration options -->
<!-- MUSICA configuration options -->

<entry id="filename_of_micm_configuration">
<type>char*512</type>
<category>musica</category>
<group>micm</group>
<group>musica</group>
<standard_name>filename_of_micm_configuration</standard_name>
<units>none</units>
<desc>
Expand Down
Loading