Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ebe3194
rad_cnst/aerosol abstract interface refactor and extension phases 1 t…
jimmielin Feb 21, 2026
c6430f1
fixup! phys_state subsetting cannot be assumed shape for chunking
jimmielin Mar 12, 2026
60811a3
cleanup: use public active_calls; clean use statements
jimmielin Mar 12, 2026
48871c6
Refactor aerosol_optics_cam to extract portable aerosol_optics_core
jimmielin Mar 11, 2026
5f200d9
Unify names for aerosol_mmr_cam to make port easier to CAM-SIMA.
jimmielin Mar 13, 2026
9ac36dd
Clarify num_to_mass_aer, dryrad for modal, sectional; fix null pointe…
jimmielin Mar 13, 2026
73aa9d2
Sync radiative_aerosol_definitions.F90 with version in CAM-SIMA
jimmielin Mar 16, 2026
a78c9aa
Address review comments
jimmielin Mar 20, 2026
d68d2d8
Remove strange dash that crept into comments
jimmielin Mar 24, 2026
7103f75
Fix and update comments throughout.
jimmielin Mar 24, 2026
867ddfb
Use pointer optional argument as suggested by @fvitt; update comment …
jimmielin Mar 24, 2026
c750e8c
Merge branch 'cam_development' into hplin/rad_cnst_refactor_5_optics
jimmielin Mar 24, 2026
545ddbf
Remove dead code in modal_aero_data (migrated into modal_aerosol_state)
jimmielin Mar 25, 2026
73c8831
Fix palb, pasm comment? in aerosol_optics_mod.F90
jimmielin Mar 25, 2026
26a6dea
Merge branch 'cam_development' into hplin/rad_cnst_refactor_5_optics
jimmielin Apr 1, 2026
372fa29
Address review comments
jimmielin Apr 1, 2026
7442ca0
Update src/chemistry/aerosol/aerosol_state_mod.F90
jimmielin Apr 1, 2026
1f0e160
Update src/physics/cam/nucleate_ice_cam.F90
jimmielin Apr 1, 2026
4f190f0
Update src/chemistry/aerosol/aerosol_state_mod.F90
jimmielin Apr 1, 2026
cf78638
generalized optics_params method instead of concrete duplicate implem…
jimmielin Apr 1, 2026
c6fbc25
remove modal_aero_data dependency in modal_aero_state_mod: refactor c…
jimmielin Apr 1, 2026
ec0784f
Fix typo throughout
jimmielin Apr 2, 2026
f9591e1
Merge branch 'cam_development' into hplin/rad_cnst_refactor_5_optics
jimmielin Apr 2, 2026
a8d344c
Apply list_idx changes to new code in cam6_4_162
jimmielin Apr 2, 2026
5819264
Fix bin_ndx -> bin_idx (this module mixes both)
jimmielin Apr 2, 2026
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
44 changes: 23 additions & 21 deletions src/chemistry/aerosol/aero_wetdep_cam.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ module aero_wetdep_cam
use cam_history, only: addfld, add_default, horiz_only, outfld
use wetdep, only: wetdep_init

use rad_constituents, only: rad_cnst_get_info
use radiative_aerosol, only: rad_aer_get_info

use aerosol_properties_mod, only: aero_name_len
use aerosol_properties_mod, only: aerosol_properties
use modal_aerosol_properties_mod, only: modal_aerosol_properties
use carma_aerosol_properties_mod, only: carma_aerosol_properties

use aerosol_state_mod, only: aerosol_state, ptr2d_t
use modal_aerosol_state_mod, only: modal_aerosol_state
use carma_aerosol_state_mod, only: carma_aerosol_state
use aerosol_instances_mod, only: aerosol_instances_get_state, &
aerosol_instances_get_props, &
aerosol_instances_get_num_models

use aero_convproc, only: aero_convproc_readnl, aero_convproc_init, aero_convproc_intr
use aero_convproc, only: convproc_do_evaprain_atonce
Expand Down Expand Up @@ -172,7 +173,7 @@ subroutine aero_wetdep_init( )
history_chemistry_out=history_chemistry, &
convproc_do_aer_out = convproc_do_aer)

call rad_cnst_get_info(0, nmodes=nmodes, nbins=nbins)
call rad_aer_get_info(0, nmodes=nmodes, nbins=nbins)

if (nmodes>0) then
aero_props => modal_aerosol_properties()
Expand Down Expand Up @@ -409,26 +410,30 @@ subroutine aero_wetdep_tend( state, dt, dlf, cam_out, ptend, pbuf)
real(r8) :: sflxbc(pcols), sflxbcdp(pcols) ! deposition flux

class(aerosol_state), pointer :: aero_state
class(aerosol_properties), pointer :: props_tmp
integer :: iaermod

nullify(aero_state)

if (.not.wetdep_active) return

dcondt_resusp3d(:,:,:) = 0._r8

if (nmodes>0) then
aero_state => modal_aerosol_state(state,pbuf)
if (.not.associated(aero_state)) then
call endrun(subrname//' : construction of aero_state modal_aerosol_state object failed')
end if
else if (nbins>0) then
aero_state => carma_aerosol_state(state,pbuf)
if (.not.associated(aero_state)) then
call endrun(subrname//' : construction of aero_state carma_aerosol_state object failed')
!REMOVECAM - get persistent state from factory; under CAM-SIMA states will be passed as scheme inputs
nullify(aero_state)
do iaermod = 1, aerosol_instances_get_num_models()
props_tmp => aerosol_instances_get_props(iaermod, 0)
if (associated(props_tmp)) then
if (.not. props_tmp%model_is('BAM')) then
aero_state => aerosol_instances_get_state(iaermod, 0, state%lchnk)
exit
end if
end if
else
call endrun(subrname//' : cannot determine aerosol model')
endif
end do
if (.not.associated(aero_state)) then
call endrun(subrname//' : no non-BAM aerosol state available for wetdep')
end if
!REMOVECAM_END

lchnk = state%lchnk
ncol = state%ncol
Expand Down Expand Up @@ -601,7 +606,7 @@ subroutine aero_wetdep_tend( state, dt, dlf, cam_out, ptend, pbuf)
qqcw_in(:ncol,:) = qqcw(mm)%fld(:ncol,:)
end if

f_act_conv(:ncol,:) = aero_state%convcld_actfrac( m, l, ncol, pver)
f_act_conv(:ncol,:) = aero_state%convcld_actfrac( aero_props, m, l, ncol, pver)
name = aname
end if

Expand Down Expand Up @@ -796,10 +801,7 @@ subroutine aero_wetdep_tend( state, dt, dlf, cam_out, ptend, pbuf)

end do bins_loop

if (associated(aero_state)) then
deallocate(aero_state)
nullify(aero_state)
end if
nullify(aero_state)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we deallocate before nullify to prevent memory leaks?

Copy link
Copy Markdown
Member Author

@jimmielin jimmielin Apr 4, 2026

Choose a reason for hiding this comment

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

Thanks for the question. For most modules excluding microp_aero.F90 (which has intermediate state1 updates) the aerosol properties and aerosol state modules are persistently allocated by aerosol_instances_mod.F90:

  ! Persistent aerosol properties objects
  ! dimensioned (iaermod, 0:N_DIAG).
  type(aero_props_entry_t), allocatable, target :: aero_props_all(:,:)

  ! Persistent per-chunk aerosol state objects
  ! dimensioned (iaermod, 0:N_DIAG, begchunk:endchunk).
  ! States store pointers to phys_state(c) and pbuf which persist for the run.
  type(aero_state_entry_t), allocatable, target :: aero_states_all(:,:,:)

https://github.com/jimmielin/CAM/blob/hplin/rad_cnst_refactor_5_optics/src/chemistry/aerosol/aerosol_instances_mod.F90

so the aero_wetdep_cam.F90's aero_state is just pointing to that persistent state:

    !REMOVECAM - get persistent state from factory; under CAM-SIMA states will be passed as scheme inputs
    nullify(aero_state)
    do iaermod = 1, aerosol_instances_get_num_models()
       props_tmp => aerosol_instances_get_props(iaermod, 0)
       if (associated(props_tmp)) then
          if (.not. props_tmp%model_is('BAM')) then
             aero_state => aerosol_instances_get_state(iaermod, 0, state%lchnk)

https://github.com/jimmielin/CAM/blob/hplin/rad_cnst_refactor_5_optics/src/chemistry/aerosol/aero_wetdep_cam.F90

at the end of the subroutine it only has to be nullify()'d but the state should not be deallocated as it is managed by aerosol_instances_mod.F90.

In the future in CAM-SIMA aero_state, aero_props will be provided as subroutine input pointers so the nullify will also not be necessary. (and the chunk dimension will also be gone.)

Differently, in microp_aero.F90, because of aero_state requiring access to state1 and not state (since there are aerosol tendencies in ice nucleation) it is created within microp_aero_run:

   !REMOVECAM: when microp_aero is brought into SIMA intermediate state1 updates should split into separate
   ! physics schemes, run tendency updaters, then the aerosol state is updated, so no need for factory pattern.
   ! create aerosol state objects via factory
   call aerosol_instances_create_states(list_idx=0, state=state1, pbuf=pbuf, aero_states=aero_states1, nstates=nstates1)
   !REMOVECAM_END

thus there is a destructor call at the end that deallocates the state object:

   ! destroy all aerosol state objects created for this chunk
   nullify(aero_state1_obj)
   call aerosol_instances_destroy_states(aero_states1)

https://github.com/jimmielin/CAM/blob/hplin/rad_cnst_refactor_5_optics/src/physics/cam/microp_aero.F90

In CAM-SIMA there won't be "intermediate states" like this (instead they're split into separate schemes running sequentially and the tendencies are updated in-between) so in the CAM-SIMA implementation there will be no aerosol_instances_{create,destroy}_states: subroutines do not need to manage aero_props/aero_state anymore and they are all just passed as input pointers


! if the user has specified prescribed aerosol dep fluxes then
! do not set cam_out dep fluxes according to the prognostic aerosols
Expand Down
Loading
Loading