Skip to content

Commit

Permalink
Merge pull request #134 from ESCOMP/94-tuvx-height-grid
Browse files Browse the repository at this point in the history
Add TUV-x height grid updates
  • Loading branch information
boulderdaze authored Oct 23, 2024
2 parents e95c172 + 76a26ee commit fbcf356
Show file tree
Hide file tree
Showing 21 changed files with 936 additions and 397 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,14 @@ jobs:
- name: build Docker image
run: docker build -t musica -f test/docker/Dockerfile.musica .
- name: run tests in container
run: docker run --name test-container -t musica bash -c 'make test ARGS="--rerun-failed --output-on-failure -j8"'
run: docker run --name test-container -t musica bash -c 'make test ARGS="--rerun-failed --output-on-failure -j8"'
test_musica_api_no_install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: build Docker image
run: docker build -t musica-no-install -f test/docker/Dockerfile.musica.no_install .
- name: run tests in container
run: docker run --name test-container -t musica-no-install bash -c 'make test ARGS="--rerun-failed --output-on-failure -j8"'
107 changes: 56 additions & 51 deletions schemes/musica/micm/musica_ccpp_micm.F90
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module musica_ccpp_micm
use iso_c_binding

! Note: "micm_t" is included in an external pre-built MICM library that the host
! model is responsible for linking to during compilation
Expand All @@ -17,50 +16,52 @@ module musica_ccpp_micm

contains

!> Register MICM constituents with the CCPP
subroutine micm_register(constituents, solver_type, num_grid_cells, errmsg, errcode)
!> Register MICM constituent properties with the CCPP
subroutine micm_register(solver_type, num_grid_cells, constituent_props, errmsg, errcode)
use ccpp_constituent_prop_mod, only: ccpp_constituent_properties_t
use musica_micm, only: Rosenbrock, RosenbrockStandardOrder
use musica_util, only: error_t
use musica_micm, only: Rosenbrock, RosenbrockStandardOrder
use musica_util, only: error_t
use iso_c_binding, only: c_int

type(ccpp_constituent_properties_t), allocatable, intent(out) :: constituents(:)
integer(c_int), intent(in) :: solver_type
integer(c_int), intent(in) :: num_grid_cells
type(ccpp_constituent_properties_t), allocatable, intent(out) :: constituent_props(:)
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errcode

! local variables
type(error_t) :: error
real(kind=kind_phys) :: molar_mass
logical :: is_advected
integer :: i

errcode = 0
errmsg = ''
type(error_t) :: error
real(kind=kind_phys) :: molar_mass
character(len=:), allocatable :: species_name
logical :: is_advected
integer :: i, species_index

micm => micm_t(filename_of_micm_configuration, solver_type, num_grid_cells, error)
if (has_error_occurred(error, errmsg, errcode)) return

allocate(constituents(size(micm%species_ordering)), stat=errcode)
allocate(constituent_props(micm%species_ordering%size()), stat=errcode)
if (errcode /= 0) then
errmsg = "[MUSICA Error] Failed to allocate memory for constituents."
errmsg = "[MUSICA Error] Failed to allocate memory for constituent properties."
return
end if

do i = 1, size(micm%species_ordering)
associate( map => micm%species_ordering(i) )
molar_mass = micm%get_species_property_double(map%name(), &
do i = 1, micm%species_ordering%size()
associate( map => micm%species_ordering )
species_name = map%name(i)
species_index = map%index(i)

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

call constituents(map%index())%instantiate( &
std_name = map%name(), &
long_name = map%name(), &
call constituent_props(species_index)%instantiate( &
std_name = species_name, &
long_name = species_name, &
units = 'kg kg-1', &
vertical_dim = 'vertical_layer_dimension', &
default_value = 0.0_kind_phys, &
Expand All @@ -78,27 +79,28 @@ end subroutine micm_register
!> Intitialize MICM
subroutine micm_init(errmsg, errcode)
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errcode
integer, intent(out) :: errcode

errcode = 0
errmsg = ''
errcode = 0

end subroutine micm_init

!> Solve chemistry at the current time step
subroutine micm_run(time_step, temperature, pressure, dry_air_density, constituents, &
rate_params, errmsg, errcode)
use musica_micm, only: solver_stats_t
use musica_util, only: string_t, error_t

real(kind_phys), intent(in) :: time_step ! s
real(c_double), target, intent(in) :: temperature(:) ! K
real(c_double), target, intent(in) :: pressure(:) ! Pa
real(c_double), target, intent(in) :: dry_air_density(:) ! kg m-3
real(c_double), target, intent(inout) :: constituents(:) ! mol m-3
real(c_double), target, intent(inout) :: rate_params(:)
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errcode
subroutine micm_run(time_step, temperature, pressure, dry_air_density, &
user_defined_rate_parameters, constituents, errmsg, errcode)
use musica_micm, only: solver_stats_t
use musica_util, only: string_t, error_t
use iso_c_binding, only: c_double

real(kind_phys), intent(in) :: time_step ! s
real(c_double), intent(in) :: temperature(:) ! K
real(c_double), intent(in) :: pressure(:) ! Pa
real(c_double), intent(in) :: dry_air_density(:) ! kg m-3
real(c_double), intent(in) :: user_defined_rate_parameters(:) ! various units
real(c_double), intent(inout) :: constituents(:) ! mol m-3
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errcode

! local variables
type(string_t) :: solver_state
Expand All @@ -107,18 +109,16 @@ subroutine micm_run(time_step, temperature, pressure, dry_air_density, constitue
real(c_double) :: c_time_step
integer :: i_elem

errcode = 0
errmsg = ''
c_time_step = real(time_step, c_double)

call micm%solve(c_time_step, &
temperature, &
pressure, &
dry_air_density, &
constituents, &
rate_params, &
solver_state, &
solver_stats, &
call micm%solve(c_time_step, &
temperature, &
pressure, &
dry_air_density, &
constituents, &
user_defined_rate_parameters, &
solver_state, &
solver_stats, &
error)
if (has_error_occurred(error, errmsg, errcode)) return

Expand All @@ -127,10 +127,15 @@ end subroutine micm_run
!> Finalize MICM
subroutine micm_final(errmsg, errcode)
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errcode
integer, intent(out) :: errcode

errcode = 0
errmsg = ''
errcode = 0

if (associated( micm )) then
deallocate( micm )
micm => null()
end if

end subroutine micm_final

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module micm_util
module musica_ccpp_micm_util
implicit none

private
Expand All @@ -7,94 +7,70 @@ module micm_util

contains

subroutine reshape_into_micm_arr(temperature, pressure, dry_air_density, constituents, &
rate_params, m_temperature, m_pressure, m_dry_air_density, m_constituents, m_rate_params)
!> Reshape array (2D/3D -> 1D) and convert type (kind_phys -> c_double)
subroutine reshape_into_micm_arr(temperature, pressure, dry_air_density, constituents, &
micm_temperature, micm_pressure, micm_dry_air_density, &
micm_constituents)
use iso_c_binding, only: c_double
use ccpp_kinds, only: kind_phys

real(kind_phys), target, intent(in) :: temperature(:,:) ! K
real(kind_phys), target, intent(in) :: pressure(:,:) ! Pa
real(kind_phys), target, intent(in) :: dry_air_density(:,:) ! kg m-3
real(kind_phys), target, intent(in) :: constituents(:,:,:) ! kg kg-1
real(kind_phys), target, intent(in) :: rate_params(:,:,:)
real(c_double), target, intent(out) :: m_temperature(:) ! K
real(c_double), target, intent(out) :: m_pressure(:) ! Pa
real(c_double), target, intent(out) :: m_dry_air_density(:) ! kg m-3
real(c_double), target, intent(out) :: m_constituents(:) ! kg kg-1
real(c_double), target, intent(out) :: m_rate_params(:)
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(kind_phys), intent(in) :: constituents(:,:,:) ! kg kg-1
real(c_double), intent(out) :: micm_temperature(:) ! K
real(c_double), intent(out) :: micm_pressure(:) ! Pa
real(c_double), intent(out) :: micm_dry_air_density(:) ! kg m-3
real(c_double), intent(out) :: micm_constituents(:) ! kg kg-1

! local variables
integer :: num_columns, num_layers
integer :: num_constituents, num_rate_params
integer :: i_column, i_layer, i_elem, i_constituents, i_rate_params
integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_elem, i_constituents

num_columns = size(constituents, dim=1)
num_layers = size(constituents, dim=2)
num_constituents = size(constituents, dim=3)
num_rate_params = size(rate_params, dim=3)

! Reshape into 1-D arry in species-column first order
! refers to: state.variables_[i_cell][i_species] = concentrations[i_species_elem++]
! Reshape into 1-D arry in species-column first order, referring to
! state.variables_[i_cell][i_species] = concentrations[i_species_elem++]
i_elem = 1
i_constituents = 1
i_rate_params = 1
do i_layer = 1, num_layers
do i_column = 1, num_columns
m_temperature(i_elem) = real(temperature(i_column, i_layer), c_double)
m_pressure(i_elem) = real(pressure(i_column, i_layer), c_double)
m_dry_air_density(i_elem) = real(dry_air_density(i_column, i_layer), c_double)
m_constituents(i_constituents : i_constituents + num_constituents - 1) &
micm_temperature(i_elem) = real(temperature(i_column, i_layer), c_double)
micm_pressure(i_elem) = real(pressure(i_column, i_layer), c_double)
micm_dry_air_density(i_elem) = real(dry_air_density(i_column, i_layer), c_double)
micm_constituents(i_constituents : i_constituents + num_constituents - 1) &
= real(constituents(i_column, i_layer, :), c_double)
m_rate_params(i_rate_params : i_rate_params + num_rate_params - 1) &
= real(rate_params(i_column, i_layer, :), c_double)
i_elem = i_elem + 1
i_constituents = i_constituents + num_constituents
i_rate_params = i_rate_params + num_rate_params
end do
end do

end subroutine reshape_into_micm_arr

subroutine reshape_into_ccpp_arr(temperature, pressure, dry_air_density, constituents, &
rate_params, m_temperature, m_pressure, m_dry_air_density, m_constituents, m_rate_params)
!> Reshape array (1D -> 3D) and convert type (c_double -> kind_phys)
subroutine reshape_into_ccpp_arr(micm_constituents, constituents)
use iso_c_binding, only: c_double
use ccpp_kinds, only: kind_phys
real(kind_phys), intent(out) :: temperature(:,:) ! K
real(kind_phys), intent(out) :: pressure(:,:) ! Pa
real(kind_phys), intent(out) :: dry_air_density(:,:) ! kg m-3
real(kind_phys), intent(out) :: constituents(:,:,:) ! kg kg-1
real(kind_phys), intent(out) :: rate_params(:,:,:)
real(c_double), intent(in) :: m_temperature(:) ! K
real(c_double), intent(in) :: m_pressure(:) ! Pa
real(c_double), intent(in) :: m_dry_air_density(:) ! kg m-3
real(c_double), intent(in) :: m_constituents(:) ! kg kg-1
real(c_double), intent(in) :: m_rate_params(:)

real(c_double), intent(in) :: micm_constituents(:) ! kg kg-1
real(kind_phys), intent(inout) :: constituents(:,:,:) ! kg kg-1

! local variables
integer :: num_columns, num_layers
integer :: num_constituents, num_rate_params
integer :: i_column, i_layer, i_elem, i_constituents, i_rate_params
integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_constituents

num_columns = size(constituents, dim=1)
num_layers = size(constituents, dim=2)
num_constituents = size(constituents, dim=3)
num_rate_params = size(rate_params, dim=3)

i_elem = 1
i_constituents = 1
i_rate_params = 1
do i_layer = 1, num_layers
do i_column = 1, num_columns
temperature(i_column, i_layer) = real(m_temperature(i_elem), kind_phys)
pressure(i_column, i_layer) = real(m_pressure(i_elem), kind_phys)
dry_air_density(i_column, i_layer) = real(m_dry_air_density(i_elem), kind_phys)
constituents(i_column, i_layer, :) &
= real(m_constituents(i_constituents : i_constituents + num_constituents - 1), kind_phys)
rate_params(i_column, i_layer, :) &
= real(m_rate_params(i_rate_params : i_rate_params + num_rate_params - 1), kind_phys)
i_elem = i_elem + 1
= real(micm_constituents(i_constituents : i_constituents + num_constituents - 1), kind_phys)
i_constituents = i_constituents + num_constituents
i_rate_params = i_rate_params + num_rate_params
end do
end do

Expand All @@ -108,6 +84,7 @@ subroutine convert_to_mol_per_cubic_meter(dry_air_density, molar_mass_arr, const
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

! local variables
integer :: num_columns, num_layers, num_constituents
integer :: i_column, i_layer, i_elem
real(kind_phys) :: val
Expand Down Expand Up @@ -156,4 +133,4 @@ subroutine convert_to_mass_mixing_ratio(dry_air_density, molar_mass_arr, constit

end subroutine convert_to_mass_mixing_ratio

end module micm_util
end module musica_ccpp_micm_util
Loading

0 comments on commit fbcf356

Please sign in to comment.