19 INTEGER,
PARAMETER ::
n_rk = 7
55 USE plume_module, ONLY:
s ,
u ,
v ,
w ,
x ,
y ,
z ,
vent_height ,
r ,
log10_mfr 75 CHARACTER(LEN=20) :: description
77 CHARACTER(len=8) :: x1
85 REAL(wp) :: mu_phi , sigma_phi , skew_phi
87 REAL(wp) :: mass_fract(n_part)
89 REAL(wp) :: solid_mass_flux , solid_mass_flux0
91 REAL(wp) :: solid_mass_flux_change
93 REAL(wp) :: obj_function
95 REAL(wp) :: w_old , w_oldold
96 REAL(wp) :: w_minrel , w_maxrel
103 INTEGER :: idx , idx1 , idx2
105 REAL(wp) :: rho_mix_init , rho_mix_final
107 REAL(wp) :: delta_rho
109 REAL(wp) :: x_nbl , y_nbl , wind_nbl , w_nbl, u_nbl, v_nbl, theta_nbl
110 REAL(wp) :: u_wind_nbl , v_wind_nbl
111 REAL(wp) :: deltarho_min
114 REAL(wp) :: rho_atm_old
118 REAL(wp) :: deltarho , deltarho_old
120 REAL(wp) :: partial_mf(n_sections)
122 REAL(wp) :: rhs_RK(itotal,
n_rk)
123 REAL(wp) :: rhs1_RK(itotal,
n_rk)
124 REAL(wp) :: rhs2_RK(itotal,
n_rk)
125 REAL(wp) :: f_RK(itotal,
n_rk)
128 REAL(wp) :: B_RK(
n_rk)
129 REAL(wp) :: C_RK(
n_rk)
130 REAL(wp) :: D_RK(
n_rk)
132 REAL(wp) :: f5th(itotal)
133 REAL(wp) :: f4th(itotal)
134 REAL(wp) :: fscal(itotal)
146 REAL(wp),
PARAMETER :: SAFETY = 0.9_wp
147 REAL(wp),
PARAMETER :: PGROW = -0.2_wp
148 REAL(wp),
PARAMETER :: PSHRNK = -0.25_wp
149 REAL(wp),
PARAMETER :: ERRCON = 1.89e-4_wp
151 REAL(wp) :: drho_atm_dz
157 REAL(wp) :: u_atm_nbl , v_atm_nbl
158 REAL(wp) :: u_atm_top , v_atm_top
174 IF ( dakota_flag )
THEN 176 description =
'Initial MFR' 191 delta_rho = rho_mix - rho_atm
193 rho_mix_init = rho_mix
197 WRITE(x1,
'(I2.2)') i_part
199 description =
'Mean Diameter '//trim(x1)
201 description =
'Sau. Mean Diam. '//trim(x1)
208 WRITE(x1,
'(I2.2)') i_part
210 mass_fract(i_part) = solid_partial_mass_fraction(i_part) * ( 1.0_wp - &
213 solid_mass_flux0 = solid_partial_mass_fraction(i_part) * ( 1.0_wp - &
214 gas_mass_fraction) * rho_mix *
pi_g * r**2 * w
217 IF ( write_flag )
THEN 219 mu_phi = sum( phir(:)*mom(1,:,i_part) ) / sum( mom(1,:,i_part) )
220 sigma_phi = sqrt( sum( (phir(:)-mu_phi)**2 *mom(1,:,i_part) ) / &
221 sum( mom(1,:,i_part) ) )
223 IF ( dakota_flag )
THEN 225 description =
'Init Avg Diam '//trim(x1)
229 description =
'Init Var Diam '//trim(x1)
233 description =
'Init Mass Fract '//trim(x1)
237 description =
'Init Solid Flux '//trim(x1)
261 particle_loss_rate(1:n_part,1:n_sections) = 0.0_wp
262 cum_particle_loss_rate(1:n_part,1:n_sections) = 0.0_wp
266 IF ( ( height_obj .EQ. 0.0_wp ) .OR. ( log10_mfr .EQ. 0.0_wp ) )
THEN 268 WRITE(*,*)
'WRITING ZERO EMISSION HYSPLIT FILE' 275 deltarho_min = 1000.0_wp
277 deltarho_old = 0.0_wp
287 d_rk(5) = 8.0_wp / 9.0_wp
308 a_rk(3,1) = 3.0_wp / 40.0_wp
309 a_rk(3,2) = 9.0_wp / 40.0_wp
316 a_rk(4,1) = 44.0_wp / 45.0_wp
317 a_rk(4,2) = - 56.0_wp / 15.0_wp
318 a_rk(4,3) = 32.0_wp / 9.0_wp
324 a_rk(5,1) = 19372.0_wp / 6561.0_wp
325 a_rk(5,2) = - 25360.0_wp / 2187.0_wp
326 a_rk(5,3) = 64448.0_wp / 6561.0_wp
327 a_rk(5,4) = - 212.0_wp / 729.0_wp
332 a_rk(6,1) = 9017.0_wp / 3168.0_wp
333 a_rk(6,2) = - 355.0_wp / 33.0_wp
334 a_rk(6,3) = 46732.0_wp / 5247.0_wp
335 a_rk(6,4) = 49.0_wp / 176.0_wp
336 a_rk(6,5) = - 5103.0_wp / 18656.0_wp
340 a_rk(7,1) = 35.0_wp / 384.0_wp
342 a_rk(7,3) = 500.0_wp / 1113.0_wp
343 a_rk(7,4) = 125.0_wp / 192.0_wp
344 a_rk(7,5) = - 2187.0_wp / 6784.0_wp
345 a_rk(7,6) = 11.0_wp / 84.0_wp
349 b_rk(1) = 35.0_wp / 384.0_wp
351 b_rk(3) = 500.0_wp / 1113.0_wp
352 b_rk(4) = 125.0_wp / 192.0_wp
353 b_rk(5) = - 2187.0_wp / 6784.0_wp
354 b_rk(6) = 11.0_wp / 84.0_wp
358 c_rk(1) = 5179.0_wp / 57600.0_wp
360 c_rk(3) = 7571.0_wp / 16695.0_wp
361 c_rk(4) = 393.0_wp / 640.0_wp
362 c_rk(5) = - 92097.0_wp / 339200.0_wp
363 c_rk(6) = 187.0_wp / 2100.0_wp
364 c_rk(7) = 1.0_wp / 40.0_wp
376 rho_atm_old = rho_atm
392 IF ( aggregation_flag )
THEN 398 rhs2(1:itotal) = 0.0_wp
402 fscal = abs( f_stepold)+abs(dz*rhs1+rhs2)+1.e-10
404 rhs_rk(1:itotal,1:
n_rk) = 0.0_wp
408 rungekutta:
DO i_rk = 1,
n_rk 412 ftemp(i) = f_stepold(i) + dz * sum( rhs_rk(i,1:i_rk-1) &
413 * a_rk(i_rk,1:i_rk-1) )
420 DO i_sect=1,n_sections
422 idx2 = 8+n_mom-1+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
424 bin_partial_mass_fraction(i_sect,i_part) = ftemp(idx2)
430 bin_partial_mass_fraction = bin_partial_mass_fraction / &
431 sum( bin_partial_mass_fraction )
435 DO i_sect=1,n_sections
437 idx1 = 8+0+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
438 idx2 = 8+n_mom-1+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
441 IF ( bin_partial_mass_fraction(i_sect,i_part) .LT. 0.0_wp)
THEN 444 IF (bin_partial_mass_fraction(i_sect,i_part) .GT.-1.0e-3_wp) &
447 ftemp(idx1:idx2) = 0.0_wp
467 z = z_temp + dz * d_rk(i_rk)
473 IF ( ( w .LE. 0.0_wp) .OR. ( rgasmix .LT. min(rair,rvolcgas_mix) ) ) &
480 IF ( verbose_level .GT. 0 )
THEN 482 IF ( w .LE. 0.0_wp)
THEN 484 WRITE(*,*)
'WARNING: negative velocity w= ',w
488 WRITE(*,*)
'WARNING: rgasmix =',rgasmix
490 WRITE(*,*)
'rair =',rair,
' rvolcgas_mix =',rvolcgas_mix
494 WRITE(*,*)
'reducing step-size dz= ',dz
507 rhs1_rk(1:itotal,i_rk) = rhs1(1:itotal)
509 IF ( aggregation_flag )
THEN 512 rhs2_rk(1:itotal,i_rk) = rhs2(1:itotal)
516 rhs2_rk(1:itotal,i_rk) = 0.0_wp
520 rhs_rk(1:itotal,i_rk) = rhs1_rk(1:itotal,i_rk) + rhs2_rk(1:itotal,i_rk)
528 f5th(i) = f_stepold(i) + dz * sum( rhs_rk(i,1:
n_rk) * b_rk(1:
n_rk) )
529 f4th(i) = f_stepold(i) + dz * sum( rhs_rk(i,1:
n_rk) * c_rk(1:
n_rk) )
533 errmax = maxval( abs( (f5th-f4th)/fscal ) ) / eps_rk
535 IF ( errmax .GT. 1.0_wp )
THEN 543 delta = safety*errmax**pshrnk
544 dz = sign( max(abs(dz*delta),0.1_wp*abs(dz)) , dz )
553 f(1:itotal) = f5th(1:itotal)
558 DO i_sect=1,n_sections
560 idx2 = 8+n_mom-1+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
562 bin_partial_mass_fraction(i_sect,i_part) = f(idx2)
568 bin_partial_mass_fraction = bin_partial_mass_fraction / &
569 sum( bin_partial_mass_fraction )
573 DO i_sect=1,n_sections
575 idx1 = 8+0+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
576 idx2 = 8+n_mom-1+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
579 IF ( bin_partial_mass_fraction(i_sect,i_part) .LT. 0.0_wp)
THEN 582 IF (bin_partial_mass_fraction(i_sect,i_part) .GT. -1.0e-3_wp )
THEN 584 f(idx1:idx2) = 0.0_wp
588 WRITE(*,*)
'z,dz,i_part,i_sect',z,dz,i_part,i_sect
615 IF ( ( w .LE. 0.0_wp) .OR. ( rgasmix .LT. min(rair , rvolcgas_mix) ) )
THEN 620 IF ( verbose_level .GT. 0 )
THEN 622 IF ( w .LE. 0.0_wp)
THEN 624 WRITE(*,*)
'WARNING: negative velocity w= ',w
628 WRITE(*,*)
'WARNING: rgasmix = ',rgasmix
632 WRITE(*,*)
'reducing step-size dz= ',dz
644 delta_rho = min( delta_rho , rho_mix - rho_atm )
647 deltarho = rho_mix - rho_atm
649 IF ( deltarho * deltarho_old .LT. 0.0_wp )
THEN 651 IF ( ( dz .GT. 1.0_wp ) .AND. ( deltarho .GT. 0.0_wp ) )
THEN 673 wind_nbl = sqrt( u_wind**2 + v_wind**2 )
675 drho_atm_dz = (rho_atm - rho_atm_old) / dz
677 dr_dz = ( r - r_old ) / dz
679 IF ( deltarho .GT. 0.0_wp )
THEN 694 deltarho_old = deltarho
704 DO i_sect=1,n_sections
706 idx = 9+(i_part-1)*n_sections*n_mom+(i_sect-1)*n_mom
708 particle_loss_rate(i_part,i_sect) = dz *
pi_g * &
709 sum( rhs1_rk(idx,1:
n_rk) * b_rk(1:
n_rk) )
715 cum_particle_loss_rate(1:n_part,1:n_sections) = &
716 cum_particle_loss_rate(1:n_part,1:n_sections) + &
717 particle_loss_rate(1:n_part,1:n_sections)
721 IF ( ( w_old .LT. w ) .AND. ( w_old .LT. w_oldold ) )
THEN 727 IF ( w .GT. w_maxabs ) w_maxabs = w
729 IF ( ( w_old .GT. w ) .AND. ( w_old .GT. w_oldold ) )
THEN 739 IF ( errmax .GT. errcon )
THEN 741 dz = dz * safety * ( errmax**pgrow )
750 dz = min( dz, 50.0_wp )
754 IF ( ( w .LE. 1.0e-5_wp ) .OR. ( dz .LE. 1.0e-5_wp ) )
THEN 763 IF ( write_flag)
THEN 766 WRITE(*,*)
'---------- MODEL RESULTS ----------' 772 check_sb = ( w_maxrel - w_minrel ) / w_maxabs
777 IF ( delta_rho .GT. 0.0_wp )
THEN 781 rho_mix_final = rho_mix
783 IF ( write_flag )
WRITE(*,*)
'Plume Regime: Collapsing' 786 IF ( hysplit_flag )
THEN 788 WRITE(*,*)
'WARNING: problem in hysplit file' 795 IF ( hysplit_flag )
THEN 809 IF ( check_sb .GT. eps_sb )
THEN 813 IF ( write_flag)
WRITE(*,*)
'Plume Regime: Superbuoyant' 819 IF ( write_flag)
WRITE(*,*)
'Plume Regime: Buoyant' 829 IF ( dakota_flag )
THEN 831 description =
'Column regime' 835 description =
'NBL height (atv)' 839 description =
'Plume height (atv)' 847 WRITE(x1,
'(I2.2)') i_part
849 mass_fract(i_part) = solid_partial_mass_fraction(i_part) * ( 1.0_wp - &
852 solid_mass_flux = solid_partial_mass_fraction(i_part) * ( 1.0_wp - &
853 gas_mass_fraction) * rho_mix *
pi_g * r**2 * w
855 solid_mass_flux_change = 1.0_wp - solid_mass_flux / solid_mass_flux0
858 IF ( dakota_flag )
THEN 860 mu_phi = sum( phir(:)*mom(1,:,i_part) ) / sum( mom(1,:,i_part) )
861 sigma_phi = sqrt( sum( (phir(:)-mu_phi)**2 *mom(1,:,i_part) ) / &
862 sum( mom(1,:,i_part) ) )
864 description =
'Final Avg Diam '//trim(x1)
868 description =
'Final Var Diam '//trim(x1)
872 description =
'Final Mass Fract '//trim(x1)
876 description =
'Final Mass Flux '//trim(x1)
880 description =
'Solid Flux Lost '//trim(x1)
884 description =
'VG Mass Fraction ' 886 CALL write_dakota(description,volcgas_mix_mass_fraction)
888 description =
'WV Mass Fraction ' 890 CALL write_dakota(description,water_vapor_mass_fraction)
892 description =
'LW Mass Fraction ' 894 CALL write_dakota(description,liquid_water_mass_fraction)
896 description =
'DA Mass Fraction ' 910 u_atm_nbl = u_wind_nbl
911 v_atm_nbl = v_wind_nbl
921 IF ( write_flag)
THEN 923 WRITE(*,*)
'Plume height above the vent [m] =',
plume_height 924 WRITE(*,*)
'Plume height above sea level [m] =',z
928 WRITE(*,*)
'Neutral buoyance level height above the vent [m] =',
height_nbl 929 WRITE(*,*)
'Neutral buoyance level height above sea level [m] =', &
931 WRITE(*,*)
'Plume density at neutral buoyancy level [kg/m3]',
rho_nbl 932 WRITE(*,*)
'Atmospheric density at top height [kg/m3]',rho_atm
933 WRITE(*,*)
'Radius at neutral buoyancy level [m] =',
radius_nbl 934 WRITE(*,*)
'Vertical gradient of radius at nbl: dr/dz [m/m] =',
dr_dz 935 WRITE(*,*)
'Mass flow rate at neutral buoyancy level [kg/s] =', &
937 WRITE(*,*)
'Volume flow rate at neutral buoyancy level [m3/s] =', &
939 WRITE(*,*)
'Plume vertical velocity at neutral buoyancy level [m/s] =', &
941 WRITE(*,*)
'Plume horizontal velocity at neutral buoyancy level [m/s] =',&
943 WRITE(*,*)
'Wind velocity at neutral buoyancy level [m/s] =', u_atm_nbl ,&
945 WRITE(*,*)
'Atmospheric density vertical gradient at nbl [kg/m4] =', &
947 WRITE(*,*)
'Wind velocity at plume top [m/s] =', u_atm_top ,&
953 WRITE(*,*)
'Dry air mass fraction =',dry_air_mass_fraction
954 WRITE(*,*)
'Water vapor mass fraction =',water_vapor_mass_fraction
955 WRITE(*,*)
'Other volcanic gas mass_fraction =',volcgas_mix_mass_fraction
957 WRITE(*,*)
'Gas mass fraction (volcgas + water vapor + dry air) =', &
959 WRITE(*,*)
'Particles mass fraction =',mass_fract
960 WRITE(*,*)
'Liquid water mass fraction =',liquid_water_mass_fraction
961 WRITE(*,*)
'Ice mass fraction =',ice_mass_fraction
963 WRITE(*,*)
'Water mass fraction (water vapor + liquid water + ice) =', &
966 WRITE(*,*)
'Solid partial mass distribution' 972 partial_mf(:) = mom(1,:,i_part) / sum( mom(1,:,i_part) )
974 phi_mean = sum(partial_mf(:) * phir(:))
976 WRITE(*,*)
'Particle phase:',i_part
977 WRITE(*,
"(30F8.2)") phil(n_sections:1:-1)
978 WRITE(*,
"(30F8.2)") phir(n_sections:1:-1)
979 WRITE(*,
"(30ES8.1)") partial_mf(n_sections:1:-1)
981 WRITE(*,*)
'Phi mean',phi_mean
subroutine write_zero_hysplit
Hysplit output initialization.
subroutine aggr_rate
Compute the right-hand side of the equations.
logical dakota_flag
Flag for dakota run (less files on output)
integer n_part
number of particle phases
subroutine write_dakota(description, value)
Dakota outputs.
real(wp), dimension(:), allocatable f_stepold
Integrated variables.
real(wp) u
plume x-horizontal velocity
real(wp) rho_atm
Atmospheric density.
real(wp), dimension(:), allocatable rhs2
Right-Hand Side (rhs2) aggregation terms only.
real(wp) ice_mass_fraction
mass fraction of ice in the mixture
real(wp) liquid_water_mass_fraction
mass fraction of liquid water in the mixture
real(wp) v
plume y-horizontal velocity
integer itotal
Total number of equations.
real(wp), dimension(:,:), allocatable cum_particle_loss_rate
cumulative rate of particles lost up to the integration height ( kg s^-1)
real(wp) dz0
Initial integration step.
subroutine initialize_mixture
Mixture properties initialization.
real(wp) water_vapor_mass_fraction
mass fraction of water vapor in the mixture
real(wp) dry_air_mass_fraction
mass fraction of dry air in the mixture
real(wp) x
plume location (downwind)
real(wp) rvolcgas_mix
gas constant of volcanic gases mixture ( J/(kg K) )
real(wp) volcgas_mix_mass_fraction
mass fraction of the volcanic gas in the mixture
logical hysplit_flag
Flag for hysplit run.
logical nbl_stop
Flag for hysplit output .
subroutine rate
Compute the right-hand side of the equations.
real(wp), dimension(:), allocatable f
Integrated variables.
real(wp) y
plume location (crosswind)
real(wp), dimension(:,:), allocatable bin_partial_mass_fraction
mass fraction of the bins of particle with respect to the total solid
real(wp), dimension(:), allocatable solid_partial_mass_fraction
mass fraction of the particle phases with respect to the total solid
subroutine init_aggregation
Aggregation initialization.
real(wp) rgasmix
universal constant for the mixture
subroutine initialize_plume
Plume variables initialization.
real(wp) dz
Integration step.
Gas/particles mixture module.
real(wp) rho_mix
mixture density
real(wp) s
length along plume centerline
subroutine write_column
Write outputs.
subroutine zmet
Meteo parameters.
real(wp) rair
perfect gas constant for dry air ( J/(kg K) )
real(wp), dimension(:,:,:), allocatable mom
Moments of the particles diameter.
real(wp), dimension(:), allocatable phil
left boundaries of the sections in phi-scale
real(wp), dimension(:), allocatable rhs
Right-Hand Side (rhs)
real(wp), dimension(:), allocatable rhstemp
Right-Hand Side (rhs)
real(wp) vent_height
height of the base of the plume
real(wp) z
plume vertical coordinate
real(wp) water_mass_fraction
mass fraction of water in the mixture
logical umbrella_flag
Flag to solve the model for the umbrella spreading.
real(wp), dimension(:,:), allocatable particle_loss_rate
rate of particles lost from the plume in the integration steps ( kg s^-1)
integer, parameter wp
working precision
subroutine plumerise
Main subroutine for the integration.
real(wp), dimension(:), allocatable ftemp
Integrated variables.
real(wp), dimension(:), allocatable phir
right boundaries of the sections in phi-scale
real(wp), dimension(:), allocatable rhs1
Right-Hand Side (rhs1) terms without aggregation.
subroutine initialize_meteo
Meteo parameters initialization.
subroutine lump(f_)
Calculate the lumped variables.
subroutine marching(fold, fnew, rate)
Marching s one step.
Predictor-corrector module.
subroutine unlump(f_)
Calculate physical variables from lumped variables.
real(wp) gas_mass_fraction
gas mass fraction in the mixture
real(wp) w
plume vertical velocity
integer verbose_level
Level of verbose output (0 = minimal output on screen)