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

Add TUV-x height grid updates #134

Open
wants to merge 23 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4c269e4
update TUV-x height grid from host data
mattldawson Sep 4, 2024
e1fd505
Merge branch 'development' into develop-94-tuvx-height-grid
mattldawson Sep 4, 2024
beb5126
add missing newlines
mattldawson Sep 4, 2024
afbe013
add tuvx temperature function
boulderdaze Sep 11, 2024
778a65a
Merge remote-tracking branch 'remotes/matt/develop-94-tuvx-height-gri…
boulderdaze Sep 11, 2024
fc1e9c5
set temperature edges
boulderdaze Sep 11, 2024
6ea9c50
fix module name
boulderdaze Sep 12, 2024
9642bfa
fix temperature test
boulderdaze Sep 12, 2024
e0d6f83
rewrote comments
boulderdaze Sep 12, 2024
7851097
add test
boulderdaze Sep 23, 2024
3a71dc3
add metadata cmake test
boulderdaze Sep 26, 2024
99d6dea
correct metadata
boulderdaze Sep 26, 2024
e4119ea
add height grid from host and run TUV-x for photo rate calcs
mattldawson Oct 9, 2024
0ec84f1
update musica commit in tests
mattldawson Oct 9, 2024
2261760
Merge branch 'development' into develop-94-tuvx-height-grid
mattldawson Oct 9, 2024
45ef3b6
fix typo
mattldawson Oct 9, 2024
aafd074
Merge metadata check from branch '120-test-metadata' into develop-94-…
mattldawson Oct 10, 2024
4660749
update metadata and test build script
mattldawson Oct 10, 2024
fe44583
add conversion from geopotential height to regular height
mattldawson Oct 11, 2024
e8c6b61
code review
boulderdaze Oct 15, 2024
a29d7c0
fix valgrind errors
boulderdaze Oct 16, 2024
452f068
fix minor syntax errors
boulderdaze Oct 16, 2024
e3ec7b2
Merge branch 'development' into 94-tuvx-height-grid
boulderdaze Oct 17, 2024
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
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"'
86 changes: 43 additions & 43 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,25 +79,26 @@ 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
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), 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(in) :: user_defined_rate_parameters(:) ! various units
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

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,10 @@ 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

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,69 @@ module micm_util

contains

!> Reshape array (2D/3D -> 1D) and convert type (kind_phys -> c_double)
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)
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), 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(c_double), target, intent(out) :: micm_temperature(:) ! K
real(c_double), target, intent(out) :: micm_pressure(:) ! Pa
real(c_double), target, intent(out) :: micm_dry_air_density(:) ! kg m-3
real(c_double), target, 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)
Comment on lines 63 to 65
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can we still do this when the intent of constituents is out?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think maybe the intent can be inout to get the dimension?

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

Using intent(inout) should definitely work here, and is probably the safest bet.

Comment on lines 63 to 65
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
num_columns = size(constituents, dim=1)
num_layers = size(constituents, dim=2)
num_constituents = size(constituents, dim=3)
num_columns = size(micm_constituents, dim=1)
num_layers = size(micm_constituents, dim=2)
num_constituents = size(micm_constituents, dim=3)

Should it be this instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah I found this possibly confusing. The function reshape_into_ccpp_arr() takes 1-D micm array and reshape it into 3-D CCPP array. It doesn't seem straightforward to get the dimension of CCPP array from micm array because this function does not want to know the number of columns and layers that are set when MCIM species are registered. (unless we want to do this way) I made CCPP array with intent(inout) instead of intent(out) solely to get the dimensions for the array. Any thoughts on this? I was also questioning about this.

!> Reshape array (1D -> 3D) and convert type (c_double -> kind_phys)
subroutine reshape_into_ccpp_arr(micm_constituents, constituents)

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 Down Expand Up @@ -156,4 +131,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