Skip to content

Commit 97ef422

Browse files
authored
Merge pull request #1628 from fvitt/aerosol_sad
cam6_4_195: Aerosol surface area densities refactor
2 parents 397daa0 + 20067e7 commit 97ef422

14 files changed

Lines changed: 1216 additions & 483 deletions

‎bld/build-namelist‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,6 +3898,34 @@ if ($chem =~ /_mam(\d)/) {
38983898
}
38993899
}
39003900

3901+
# SAD process participation spec_types
3902+
if ($chem =~ /_mam/) {
3903+
add_default($nl, 'sad_chem_spec_types',
3904+
'val'=>"'sulfate','s-organic','p-organic','black-c','ammonium'");
3905+
# sad_seasalt_spec_types is MAM-only: CARMA does not compute separate
3906+
# sea-salt SAD (its aero_model_surfarea sets sad_ssa to a sentinel value).
3907+
add_default($nl, 'sad_seasalt_spec_types',
3908+
'val'=>"'seasalt'");
3909+
# b4b default matches sad_chem_spec_types; mo_sad.F90 currently assumes
3910+
# all strat SAD is sulfate aerosol (see sad_strat_calc/sulfate_sad_calc).
3911+
add_default($nl, 'sad_strat_spec_types',
3912+
'val'=>"'sulfate','s-organic','p-organic','black-c','ammonium'");
3913+
}
3914+
if ($carma ne 'none' and $chem !~ /_mam/) {
3915+
add_default($nl, 'sad_chem_spec_types',
3916+
'val'=>"'sulfate','s-organic','p-organic','black-c','ammonium'");
3917+
# b4b default matches sad_chem_spec_types; mo_sad.F90 currently assumes
3918+
# all strat SAD is sulfate aerosol (see sad_strat_calc/sulfate_sad_calc).
3919+
add_default($nl, 'sad_strat_spec_types',
3920+
'val'=>"'sulfate','s-organic','p-organic','black-c','ammonium'");
3921+
}
3922+
if ($aer_model eq 'bam' and $prescribed_aero_model eq 'none') {
3923+
add_default($nl, 'sad_chem_spec_types',
3924+
'val'=>"'sulfate','black-c','p-organic','s-organic','nitrate'");
3925+
}
3926+
# ...for prescribed BAM with chemistry (WACCM-4) sad_chem_spec_types should
3927+
# be empty as sulfate is from supplemental SAD from sulf_file, not here.
3928+
39013929
# Gravity wave drag settings
39023930

39033931
# By default, orographic waves are always on

‎bld/namelist_files/namelist_definition.xml‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6784,6 +6784,43 @@ Tuning for seasalt_emis
67846784
Default: set by build-namelist.
67856785
</entry>
67866786

6787+
<entry id="sad_chem_spec_types" type="char*32(16)" category="cam_chem"
6788+
group="aerosol_nl" valid_values="" >
6789+
Species types contributing to chemistry-relevant surface area density (SAD)
6790+
for heterogeneous reaction rates. The SAD determines how much aerosol surface
6791+
is available for gas-phase chemical reactions (computed in aero_model, used
6792+
by mo_usrrxt).
6793+
6794+
In bulk (BAM) configurations, types not in rad_climate are provided by
6795+
a supplemental path in aero_model_surfarea.
6796+
6797+
Default: 'sulfate','s-organic','p-organic','black-c','ammonium' (MAM, CARMA);
6798+
'sulfate','black-c','p-organic','s-organic','nitrate' (prognostic bulk);
6799+
UNSET (prescribed bulk)
6800+
</entry>
6801+
6802+
<entry id="sad_seasalt_spec_types" type="char*32(16)" category="cam_chem"
6803+
group="aerosol_nl" valid_values="" >
6804+
Species types contributing to sea-salt surface area density (SAD).
6805+
Computed separately from chemistry SAD and used for sea-salt-specific
6806+
heterogeneous reactions.
6807+
Default: 'seasalt'
6808+
</entry>
6809+
6810+
<entry id="sad_strat_spec_types" type="char*32(16)" category="cam_chem"
6811+
group="aerosol_nl" valid_values="" >
6812+
Species types contributing to stratospheric surface area density (SAD).
6813+
Used by aero_model_strat_surfarea to compute strato_sad, which is passed
6814+
to sad_strat_calc (mo_sad.F90) for STS/NAT/ICE thermodynamic partitioning.
6815+
Note: sad_strat_calc currently assumes all incoming SAD is sulfate aerosol
6816+
(via sulfate_sad_calc and calc_radius_lbs). Supporting non-sulfate species
6817+
in the stratospheric SAD pathway requires refactoring mo_sad.F90 to handle
6818+
multiple aerosol types independently. The physically correct default would
6819+
be 'sulfate' only, but the current default matches sad_chem_spec_types for
6820+
bit-for-bit consistency with prior hardcoded behavior.
6821+
Default: 'sulfate','s-organic','p-organic','black-c','ammonium'
6822+
</entry>
6823+
67876824
<entry id="aer_sol_facti" type="real(1000)" category="cam_chem"
67886825
group="aerosol_nl" valid_values="" >
67896826
In-cloud solubility factor used in BULK aerosol wet removal

‎doc/ChangeLog‎

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,193 @@
11
===============================================================
22

3+
Tag name: cam6_4_195
4+
Originator(s): fvitt, jimmielin
5+
Date: 8 Aug 2026
6+
One-line Summary: Refactor aerosol surface area densities
7+
Github PR URL: https://github.com/ESCOMP/CAM/pull/1628
8+
9+
Purpose of changes (include the issue number and title text for each relevant GitHub issue):
10+
11+
Aerosol surface area densities abstraction
12+
#1625
13+
14+
Describe any changes made to build system: N/A
15+
16+
Describe any changes made to the namelist:
17+
18+
New namelist parameters:
19+
20+
sad_chem_spec_types
21+
Species types contributing to chemistry-relevant surface area density (SAD)
22+
for heterogeneous reaction rates. The SAD determines how much aerosol surface
23+
is available for gas-phase chemical reactions (computed in aero_model, used
24+
by mo_usrrxt).
25+
26+
In bulk (BAM) configurations, types not in rad_climate are provided by
27+
a supplemental path in aero_model_surfarea.
28+
29+
sad_seasalt_spec_types
30+
Species types contributing to sea-salt surface area density (SAD).
31+
Computed separately from chemistry SAD and used for sea-salt-specific
32+
heterogeneous reactions.
33+
34+
sad_strat_spec_types
35+
Species types contributing to stratospheric surface area density (SAD).
36+
Used by aero_model_strat_surfarea to compute strato_sad, which is passed
37+
to sad_strat_calc (mo_sad.F90) for STS/NAT/ICE thermodynamic partitioning.
38+
Note: sad_strat_calc currently assumes all incoming SAD is sulfate aerosol
39+
(via sulfate_sad_calc and calc_radius_lbs). Supporting non-sulfate species
40+
in the stratospheric SAD pathway requires refactoring mo_sad.F90 to handle
41+
multiple aerosol types independently. The physically correct default would
42+
be 'sulfate' only, but the current default matches sad_chem_spec_types for
43+
bit-for-bit consistency with prior hardcoded behavior.
44+
45+
List any changes to the defaults for the boundary datasets: N/A
46+
47+
Describe any substantial timing or memory changes: N/A
48+
49+
Code reviewed by: jimmielin
50+
51+
List all files eliminated: N/A
52+
53+
List all files added and what they do:
54+
A src/chemistry/aerosol/aerosol_spec_utils.F90
55+
- utility module for aerosol types in SAD calculations
56+
57+
List all existing files that have been modified, and describe the changes:
58+
M bld/build-namelist
59+
- set defaults SAD types lists
60+
61+
M bld/namelist_files/namelist_definition.xml
62+
- SAD types lists
63+
64+
M src/chemistry/aerosol/aerosol_state_mod.F90
65+
M src/chemistry/aerosol/bulk_aerosol_state_mod.F90
66+
M src/chemistry/aerosol/carma_aerosol_state_mod.F90
67+
M src/chemistry/aerosol/modal_aerosol_state_mod.F90
68+
- new aero_surf_area routine
69+
70+
M src/chemistry/bulk_aero/aero_model.F90
71+
- read SAD types list in namelist
72+
- invoke aero_state%surf_area
73+
- include supplemental SAD calcs for aerosols not included in rad_climate
74+
75+
M src/chemistry/carma_aero/aero_model.F90
76+
M src/chemistry/modal_aero/aero_model.F90
77+
- read SAD types list in namelist
78+
- invoke aero_state%surf_area
79+
80+
M src/chemistry/mozart/mo_gas_phase_chemdr.F90
81+
M src/chemistry/mozart/mo_usrrxt.F90
82+
- clean up args for surf area routine
83+
84+
M src/chemistry/mozart/mo_sulf.F90
85+
- move SULFATE hist outfld call to gas_phyase_chemdr
86+
87+
If there were any failures reported from running test_driver.sh on any test
88+
platform, and checkin with these failures has been OK'd by the gatekeeper,
89+
then copy the lines from the td.*.status files for the failed tests to the
90+
appropriate machine below. All failed tests must be justified.
91+
92+
derecho/intel/aux_cam:
93+
NLFAIL ERC_D_Ln9.f09_f09_mt232.FHIST_BDRD.derecho_intel.cam-outfrq9s
94+
NLFAIL ERC_D_Ln9.f19_f19_mt232.QPC6.derecho_intel.cam-outfrq3s_cosp
95+
NLFAIL ERC_D_Ln9.mpasa120_mpasa120.F2000climo.derecho_intel.cam-outfrq9s_mpasa120
96+
NLFAIL ERC_D_Ln9.mpasa120_mpasa120.FHISTC_LTso.derecho_intel.cam-outfrq9s_mpasa120
97+
NLFAIL ERC_D_Ln9.ne30pg3_ne30pg3_mt232.F1850C_LTso.derecho_intel.cam-outfrq9s
98+
NLFAIL ERC_Ln9.C96_C96_mt232.F2000climo.derecho_intel.cam-outfrq9s
99+
NLFAIL ERI_D_Ln18.f09_f09_mt232.FHIST.derecho_intel.cam-outfrq3s_eri
100+
NLFAIL ERI_D_Ln18.f19_f19_mt232.FHIST_C5.derecho_intel.cam-outfrq3s_eri
101+
NLFAIL ERI_D_Ln18.ne30pg3_ne30pg3_mt232.FHISTC_LTso.derecho_intel.cam-outfrq3s_eri
102+
NLFAIL ERP_D_Ln9.ne30pg3_ne30pg3_mt232.F1850C_MTso.derecho_intel.cam-outfrq9s
103+
NLFAIL ERP_D_Ln9_P64x2.f09_f09_mg17.QSC6.derecho_intel.cam-outfrq9s
104+
NLFAIL ERP_Ld3.ne16pg3_ne16pg3_mg17.FHISTC_WAt1ma.derecho_intel.cam-reduced_hist1d
105+
NLFAIL ERP_Ld3.ne30pg3_ne30pg3_mt232.FHISTC_MTt4s.derecho_intel.cam-outfrq1d_aoa
106+
NLFAIL ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s
107+
NLFAIL ERP_Ln9.f19_f19_mg17.FWsc1850.derecho_intel.cam-outfrq9s
108+
NLFAIL ERP_Ln9.ne30pg3_ne30pg3_mg17.FCnudged.derecho_intel.cam-outfrq9s
109+
NLFAIL ERP_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WAma.derecho_intel.cam-outfrq9s
110+
NLFAIL ERR_Ln9.ne16pg3_ne16pg3_mt232.FHISTC_LTso.derecho_intel.cam-outfrq9s_bwic
111+
NLFAIL ERS_Ln9.f09_f09_mg17.FX2000.derecho_intel.cam-outfrq9s
112+
NLFAIL ERS_Ln9.f19_f19_mg17.FXSD.derecho_intel.cam-outfrq9s
113+
NLFAIL ERS_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s_ctem
114+
NLFAIL SCT_D_Ln7.ne3_ne3_mg37.QPC5.derecho_intel.cam-scm_prep
115+
NLFAIL SMS_C2_D_Ln9.ne16pg3_ne16pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s
116+
NLFAIL SMS_D_Ld5.f09_f09_mt232.PC6.derecho_intel.cam-cam6_port_f09
117+
NLFAIL SMS_D_Ln9.f09_f09_mg17.FCts2nudged.derecho_intel.cam-outfrq9s_leapday
118+
NLFAIL SMS_D_Ln9.f09_f09_mg17.FCvbsxHIST.derecho_intel.cam-outfrq9s
119+
NLFAIL SMS_D_Ln9.f09_f09_mg17.FSD.derecho_intel.cam-outfrq9s
120+
NLFAIL SMS_D_Ln9.f19_f19_mg17.FCARMA2000climo.derecho_intel.cam-outfrq9s_carma_rad_diag
121+
NLFAIL SMS_D_Ln9.f19_f19_mg17.FCHIST_SLH.derecho_intel.cam-outfrq9s
122+
NLFAIL SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s
123+
NLFAIL SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s_waccm_ma_mam4
124+
NLFAIL SMS_D_Ln9.f19_f19_mg17.QPC2000climo.derecho_intel.cam-outfrq3s_usecase
125+
NLFAIL SMS_D_Ln9.f19_f19_mt232.FHIST_C5.derecho_intel.cam-mam7
126+
NLFAIL SMS_D_Ln9.ne0ARCTICne30x4_ne0ARCTICne30x4_mt12.FHIST.derecho_intel.cam-outfrq9s
127+
NLFAIL SMS_D_Ln9.ne30pg3_ne30pg3_mt232.1850_CAM70%MT%CT4S2_CLM60%SP_CICE%PRES_DOCN%DOM_MOSART_SGLC_SWAV_SESP.derecho_intel.cam-outfrq9s
128+
NLFAIL SMS_D_Ln9.ne30pg3_ne30pg3_mt232.FHISTC_MTso.derecho_intel.cam-outfrq9s
129+
NLFAIL SMS_D_Ln9_P1280x1.ne30pg3_ne30pg3_mt232.FHISTC_MTt1s.derecho_intel.cam-outfrq9s_Leung_dust
130+
NLFAIL SMS_D_Ln9_P1536x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s
131+
NLFAIL SMS_Ld1.f09_f09_mg17.FCHIST_GC.derecho_intel.cam-outfrq1d
132+
NLFAIL SMS_Ld1.f09_f09_mg17.FW2000climo.derecho_intel.cam-outfrq1d
133+
NLFAIL SMS_Ld1.ne30pg3_ne30pg3_mg17.FC2010climo.derecho_intel.cam-outfrq1d
134+
NLFAIL SMS_Lh12.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq3h
135+
NLFAIL SMS_Ln9.f09_f09_mg17.F2010climo.derecho_intel.cam-nudging
136+
NLFAIL SMS_Ln9.f09_f09_mg17.FW1850.derecho_intel.cam-reduced_hist3s
137+
NLFAIL SMS_Ln9.f19_f19_mt232.F2000climo.derecho_intel.cam-silhs
138+
NLFAIL SMS_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s_rrtmgp
139+
- new SAD species types lists
140+
141+
DIFF ERC_D_Ln9.f19_f19_mg17.QPMOZ.derecho_intel.cam-outfrq3s
142+
- expected baseline failure due to BAM SAD refactor
143+
144+
derecho/nvhpc/aux_cam:
145+
FAIL ERS_Ln9.ne30pg3_ne30pg3_mt232.FHISTC_LTso.derecho_nvhpc.cam-outfrq9s_gpu_default MODEL_BUILD time=0
146+
- pre-existing failure as of cam6_4_193
147+
148+
izumi/nag/aux_cam:
149+
FAIL ERC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-outfrq3s_subcol COMPARE_base_rest
150+
- pre-existing failure -- see https://github.com/ESCOMP/CAM/issues/1514
151+
152+
NLFAIL ERC_D_Ln27.ne3pg3_ne3pg3_mt232.FKESSLER.izumi_nag.cam-outfrq9s
153+
NLFAIL ERC_D_Ln9.f10_f10_mg37.QPWmaC6.izumi_nag.cam-outfrq9s_tuvx_waccm_ma_mam5
154+
NLFAIL ERC_D_Ln9.f10_f10_mt232.FHIST.izumi_nag.cam-outfrq3s_cospsathist
155+
NLFAIL ERC_D_Ln9.mpasa480_mpasa480_mt232.FHS94.izumi_nag.cam-outfrq9s
156+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHISTC_LTso.izumi_nag.cam-cosp_rad_diags
157+
NLFAIL SMS_D_Ld2.f45_f45_mg37.PC5.izumi_nag.cam-outfrq24h_port
158+
NLFAIL SMS_D_Ln9.f10_f10_mt232.F1850.izumi_nag.cam-outfrq9s
159+
NLFAIL SMS_D_Ln9.ne3pg3_ne3pg3_mt232.QPC7.izumi_nag.cam-carma_test_tracers
160+
NLFAIL TMC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-mc_ttrac
161+
- new SAD species types lists
162+
163+
izumi/gnu/aux_cam:
164+
DIFF SMS_D_Ln3.f10_f10_mg37.QPMOZ.izumi_gnu.cam-outfrq3s_chemproc
165+
- expected baseline failure due to BAM SAD refactor
166+
167+
NLFAIL ERC_D_Ln9.C48_C48_mg17.QPC6.izumi_gnu.cam-outfrq9s
168+
NLFAIL ERC_D_Ln9.f19_f19_mt232.FHIST.izumi_gnu.cam-lonlat_fv_diags
169+
NLFAIL ERC_D_Ln9.mpasa480_mpasa480_mt232.FHISTC_LTso.izumi_gnu.cam-outfrq9s_mpasa480
170+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FGRAYRAD.izumi_gnu.cam-outfrq9s
171+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHIST_C5.izumi_gnu.cam-carma_cosp_rad_diag_mam
172+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHISTC_LTso.izumi_gnu.cam-sat_lcltod
173+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FTJ16.izumi_gnu.cam-outfrq9s
174+
NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.QPC5.izumi_gnu.cam-outfrq9s
175+
NLFAIL ERS_Ln9_P24x1.mpasa480_mpasa480.F2000climo.izumi_gnu.cam-outfrq9s_mpasa480
176+
NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal0
177+
NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal1
178+
NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal3
179+
NLFAIL SCT_D_Ln7.ne3_ne3_mg37.QPC6.izumi_gnu.cam-scm_prep_c6
180+
NLFAIL SMS_D_Ln3.ne3pg3_ne3pg3_mt232.PC7.izumi_gnu.cam-pc7_ne3pg3
181+
NLFAIL SMS_D_Ln9.f10_f10_mg37.FWmaHIST.izumi_gnu.cam-outfrq9s_mee_fluxes
182+
NLFAIL SUB_D_Ln9.ne3pg3_ne3pg3_mt232.FHIST.izumi_gnu.cam-outfrq9s
183+
- new SAD species types lists
184+
185+
Summarize any changes to answers:
186+
larger than roundoff for prognostic BAM, otherwise bit-for-bit
187+
188+
===============================================================
189+
===============================================================
190+
3191
Tag name: cam6_4_194
4192
Originator(s): jimmielin
5193
Date: Aug 7, 2026
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
! Utility module for aerosol species types
2+
module aerosol_spec_utils
3+
4+
implicit none
5+
private
6+
public :: spec_type_in_list
7+
8+
contains
9+
10+
! returns TRUE if species type is found in type_list
11+
logical function spec_type_in_list(spec_type, type_list)
12+
character(len=*), intent(in) :: spec_type
13+
character(len=*), intent(in) :: type_list(:)
14+
integer :: i
15+
spec_type_in_list = .false.
16+
do i = 1, size(type_list)
17+
if (len_trim(type_list(i)) == 0) cycle
18+
if (trim(spec_type) == trim(type_list(i))) then
19+
spec_type_in_list = .true.
20+
return
21+
end if
22+
end do
23+
end function spec_type_in_list
24+
25+
end module aerosol_spec_utils

‎src/chemistry/aerosol/aerosol_state_mod.F90‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module aerosol_state_mod
6565
procedure :: convcld_actfrac
6666
procedure :: sol_factb_interstitial
6767
procedure(aero_aqu_gain_binfraction), deferred :: aqu_gain_binfraction
68+
procedure(aero_surf_area_dens), deferred :: surf_area_dens
6869

6970
end type aerosol_state
7071

@@ -299,6 +300,32 @@ subroutine aero_aqu_gain_binfraction(self, aero_props, type, qcw, delso4_o3rxn,
299300

300301
end subroutine aero_aqu_gain_binfraction
301302

303+
!------------------------------------------------------------------------
304+
! aerosol surface area density
305+
!------------------------------------------------------------------------
306+
subroutine aero_surf_area_dens(self, aero_props, types_list, ncol, nlev, beglev, endlev, &
307+
relhum, pmid, temp, pi, sad, reff, sfc, dm_aer)
308+
import :: aerosol_state, aerosol_properties, r8
309+
310+
class(aerosol_state), intent(in) :: self
311+
class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
312+
character(len=*), intent(in) :: types_list(:) ! list of aerosol types to include
313+
integer, intent(in) :: ncol ! number of columns
314+
integer, intent(in) :: nlev ! number of levels
315+
integer, intent(in) :: beglev(:) ! beginning model level index
316+
integer, intent(in) :: endlev(:) ! ending model level index
317+
real(r8), intent(in) :: relhum(:,:) ! relative humidity
318+
real(r8), intent(in) :: pmid(:,:) ! mid-level pressure (Pa)
319+
real(r8), intent(in) :: temp(:,:) ! temperature (K)
320+
real(r8), intent(in) :: pi ! pi mathematical constant
321+
322+
real(r8), intent(out) :: sad(:,:) ! surface area density (cm2/cm3)
323+
real(r8), intent(out) :: reff(:,:) ! effective radius (units cm)
324+
real(r8), optional, intent(out) :: sfc(:,:,:) ! surface area density per bin (cm2/cm3)
325+
real(r8), optional, intent(out) :: dm_aer(:,:,:) ! diameter per bin (cm)
326+
327+
end subroutine aero_surf_area_dens
328+
302329
end interface
303330

304331
contains
@@ -967,5 +994,4 @@ function sol_factb_interstitial(self, bin_ndx, ncol, nlev, aero_props) result(so
967994

968995
end function sol_factb_interstitial
969996

970-
971997
end module aerosol_state_mod

0 commit comments

Comments
 (0)