32 real(kind=
dp),
allocatable :: vol(:)
34 integer :: weight_group
36 integer :: weight_class
38 real(kind=
dp),
allocatable :: absorb_cross_sect(:)
40 real(kind=
dp),
allocatable :: scatter_cross_sect(:)
42 real(kind=
dp),
allocatable :: asymmetry(:)
44 complex(kind=dc),
allocatable :: refract_shell(:)
46 complex(kind=dc),
allocatable :: refract_core(:)
48 real(kind=
dp) :: core_vol
50 integer :: water_hyst_leg
56 real(kind=
dp) :: least_create_time
58 real(kind=
dp) :: greatest_create_time
60 integer :: n_primary_parts
79 call move_alloc(aero_particle_from%vol, aero_particle_to%vol)
80 aero_particle_to%weight_group = aero_particle_from%weight_group
81 aero_particle_to%weight_class = aero_particle_from%weight_class
82 call move_alloc(aero_particle_from%absorb_cross_sect, &
83 aero_particle_to%absorb_cross_sect)
84 call move_alloc(aero_particle_from%scatter_cross_sect, &
85 aero_particle_to%scatter_cross_sect)
86 call move_alloc(aero_particle_from%asymmetry, &
87 aero_particle_to%asymmetry)
88 call move_alloc(aero_particle_from%refract_shell, &
89 aero_particle_to%refract_shell)
90 call move_alloc(aero_particle_from%refract_core, &
91 aero_particle_to%refract_core)
92 aero_particle_to%core_vol = aero_particle_from%core_vol
93 aero_particle_to%water_hyst_leg = aero_particle_from%water_hyst_leg
94 aero_particle_to%id = aero_particle_from%id
95 call move_alloc(aero_particle_from%component, aero_particle_to%component)
96 aero_particle_to%least_create_time = aero_particle_from%least_create_time
97 aero_particle_to%greatest_create_time = &
98 aero_particle_from%greatest_create_time
99 aero_particle_to%n_primary_parts = aero_particle_from%n_primary_parts
114 aero_particle%vol = 0d0
115 aero_particle%weight_group = 0
116 aero_particle%weight_class = 0
118 aero_particle%absorb_cross_sect = 0d0
120 aero_particle%scatter_cross_sect = 0d0
122 aero_particle%asymmetry = 0d0
124 aero_particle%refract_shell = (0d0, 0d0)
126 aero_particle%refract_core = (0d0, 0d0)
127 aero_particle%core_vol = 0d0
128 aero_particle%water_hyst_leg = 0
130 if (
allocated(aero_particle%component))
deallocate(aero_particle%component)
131 allocate(aero_particle%component(0))
132 aero_particle%least_create_time = 0d0
133 aero_particle%greatest_create_time = 0d0
134 aero_particle%n_primary_parts = 0
159 real(kind=
dp),
intent(in) :: create_time
161 aero_particle%component(1)%create_time = create_time
162 aero_particle%least_create_time = create_time
163 aero_particle%greatest_create_time = create_time
175 integer,
intent(in) :: i_source
177 real(kind=
dp),
intent(in) :: create_time
179 if (
allocated(aero_particle%component))
deallocate(aero_particle%component)
180 allocate(aero_particle%component(1))
194 integer,
intent(inout) :: source_list(:)
196 integer :: i_comp, i_source
199 i_source = aero_particle%component(i_comp)%source_id
200 source_list(i_source) = source_list(i_source) + 1
213 real(kind=
dp),
intent(in) :: vols(:)
215 aero_particle%vol = vols
227 integer,
intent(in) :: i_source
229 aero_particle%component(1)%source_id = i_source
241 integer,
intent(in),
optional :: i_group
243 integer,
intent(in),
optional :: i_class
245 if (
present(i_group)) aero_particle%weight_group = i_group
246 if (
present(i_class)) aero_particle%weight_class = i_class
273 integer,
intent(in) :: i_spec
278 * aero_data%density(i_spec)
310 / aero_data%molec_weight)
330 aero_particle, i_spec)
335 integer,
intent(in) :: i_spec
356 if (i_spec /= aero_data%i_water)
then
358 + aero_particle%vol(i_spec)
368 aero_particle, aero_data, dry_volume)
375 logical,
intent(in) :: dry_volume
454 aero_data, env_state)
463 real(kind=
dp) :: volume, mobility_radius
466 mobility_radius = fractal_vol_to_mobility_rad(aero_data%fractal, &
467 volume, env_state%temp, env_state%pressure)
491 aero_particle, aero_data, quantity)
498 real(kind=
dp),
intent(in) :: quantity(:)
505 aero_data, quantity) &
521 real(kind=
dp),
intent(in) :: quantity(:)
528 if (i /= aero_data%i_water)
then
529 total = total + aero_particle%vol(i) * quantity(i)
547 real(kind=
dp),
intent(in) :: quantity(:)
549 call assert(420016623, aero_data%i_water > 0)
565 real(kind=
dp),
intent(in) :: quantity(:)
567 call assert(223343210, aero_data%i_water > 0)
569 = aero_particle%vol(aero_data%i_water) &
570 * quantity(aero_data%i_water)
583 call assert(772012490, aero_data%i_water > 0)
585 = aero_data%molec_weight(aero_data%i_water)
602 aero_data, aero_data%molec_weight)
619 aero_data, real(aero_data%num_ions, kind=
dp))
631 call assert(235482108, aero_data%i_water > 0)
649 aero_data, aero_data%density)
663 call assert(888636139, aero_data%i_water > 0)
665 * aero_data%density(aero_data%i_water)
681 aero_data, aero_data%density)
738 if (i_spec == aero_data%i_water)
then
740 elseif (aero_data%num_ions(i_spec) > 0)
then
741 call assert_msg(123681459, aero_data%kappa(i_spec) == 0d0, &
742 "species has nonzero num_ions and kappa: " &
743 // trim(aero_data%name(i_spec)))
744 m_a = aero_data%molec_weight(i_spec)
745 rho_a = aero_data%density(i_spec)
746 kappa(i_spec) = m_w * rho_a / (m_a * rho_w) &
747 * real(aero_data%num_ions(i_spec), kind=
dp)
749 kappa(i_spec) = aero_data%kappa(i_spec)
762 aero_data, env_state)
771 real(kind=
dp) :: kappa, diam, c, a
784 aero_data, env_state)
793 real(kind=
dp) :: kappa, crit_diam, dry_diam, a
800 if (kappa < 1d-30)
then
804 / (crit_diam**3 - dry_diam**3 * (1 - kappa)) * exp(a / crit_diam)
851 aero_data, env_state)
860 integer,
parameter :: crit_diam_max_iter = 100
862 real(kind=
dp) :: kappa, dry_diam, a, c4, c3, c0, d, f, df, dd
868 if (kappa < 1d-30)
then
874 c4 = - 3d0 * dry_diam**3 * kappa / a
875 c3 = - dry_diam**3 * (2d0 - kappa)
876 c0 = dry_diam**6 * (1d0 - kappa)
879 d = max(sqrt(-4d0 / 3d0 * c4), (-c3)**(1d0/3d0))
880 do i_newton = 1,crit_diam_max_iter
881 f = d**6 + c4 * d**4 + c3 * d**3 + c0
882 df = 6 * d**5 + 4 * c4 * d**3 + 3 * c3 * d**2
885 if (abs(dd / d) < 1d-14)
then
890 "critical diameter Newton loop failed to converge")
892 "critical diameter Newton loop converged to invalid solution")
902 aero_particle_2, aero_particle_new)
911 integer :: n_comp_1, n_comp_2, n_comp_1_new, n_comp_2_new, i
914 integer,
allocatable :: sample(:)
916 call assert(203741686,
size(aero_particle_1%vol) &
917 ==
size(aero_particle_2%vol))
918 aero_particle_new%vol = aero_particle_1%vol + aero_particle_2%vol
919 aero_particle_new%weight_group = 0
920 aero_particle_new%weight_class = 0
921 n_swbands =
size(aero_particle_1%absorb_cross_sect)
928 aero_particle_new%absorb_cross_sect = 0d0
929 aero_particle_new%scatter_cross_sect = 0d0
930 aero_particle_new%asymmetry = 0d0
931 aero_particle_new%refract_shell = (0d0, 0d0)
932 aero_particle_new%refract_core = (0d0, 0d0)
933 aero_particle_new%core_vol = 0d0
934 if ((aero_particle_1%water_hyst_leg == 1) &
935 .and. (aero_particle_2%water_hyst_leg == 1))
then
936 aero_particle_new%water_hyst_leg = 1
938 aero_particle_new%water_hyst_leg = 0
940 aero_particle_new%id = 0
942 call assert_msg(465791384, aero_particle_1%n_primary_parts >= &
943 n_comp_1,
'n_primary_parts = ' &
945 //
' is less than n_components = ' &
948 call assert_msg(465791385, aero_particle_2%n_primary_parts >= &
949 n_comp_2,
'n_primary_parts = ' &
951 //
' is less than n_components = ' &
954 n_comp_1_new =
prob_round(real(aero_particle_1%n_primary_parts, &
955 kind=
dp) / (aero_particle_1%n_primary_parts &
960 do i = 1,n_comp_1_new
961 new_aero_component(i) = aero_particle_1%component(sample(i))
964 do i = 1,n_comp_2_new
965 new_aero_component(i+n_comp_1_new) = aero_particle_2%component( &
968 aero_particle_new%component = new_aero_component
970 new_aero_component = [aero_particle_1%component, &
971 aero_particle_2%component]
972 call move_alloc(new_aero_component, aero_particle_new%component)
974 aero_particle_new%least_create_time = &
975 min(aero_particle_1%least_create_time, &
976 aero_particle_2%least_create_time)
977 aero_particle_new%greatest_create_time = &
978 max(aero_particle_1%greatest_create_time, &
979 aero_particle_2%greatest_create_time)
981 aero_particle_new%n_primary_parts = aero_particle_1%n_primary_parts &
982 + aero_particle_2%n_primary_parts
994 if (
allocated(particle%component))
then
1042 character,
intent(inout) :: buffer(:)
1044 integer,
intent(inout) :: position
1049 integer :: prev_position, i
1051 prev_position = position
1071 call assert(810223998, position - prev_position &
1083 character,
intent(inout) :: buffer(:)
1085 integer,
intent(inout) :: position
1090 integer :: prev_position, n_components, i
1092 prev_position = position
1105 if (n_components > -1)
then
1106 allocate(val%component(n_components))
1108 do i = 1,n_components
1114 call assert(287447241, position - prev_position &
1131 logical,
intent(in) :: continue_on_error
1133 if (
allocated(aero_particle%vol))
then
1135 write(0, *)
'ERROR aero_particle A:'
1136 write(0, *)
'size(aero_particle%vol)',
size(aero_particle%vol)
1137 write(0, *)
'aero_data_n_spec(aero_data)', &
1139 call assert(185878626, continue_on_error)