Ignore:
Timestamp:
Feb 17, 2012 9:09:57 AM (12 years ago)
Author:
raasch
Message:

preliminary checkin of new curvature/solution effects on droplet growth

File:
1 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/SOURCE/advec_particles.f90

    r800 r824  
    44! Current revisions:
    55! ------------------
    6 !
     6! droplet growth by condensation may include curvature and solution effects.
     7! initialisation of temporary particle array for resorting removed.
     8! particle attributes speed_x|y|z_sgs renamed rvar1|2|3.
    79!
    810! Former revisions:
     
    137139    IMPLICIT NONE
    138140
    139     INTEGER ::  agp, deleted_particles, deleted_tails, i, ie, ii, inc, is, j,  &
    140                 jj, js, k, kk, kw, m, n, nc, nd, nn, num_gp, pse, psi,         &
     141    INTEGER ::  agp, deleted_particles, deleted_tails, i, ie, ii, inc,         &
     142                internal_timestep_count, is, j,  &
     143                jj, js, jtry, k, kk, kw, m, n, nc, nd, nn, num_gp, pse, psi,   &
    141144                tlength, trlp_count, trlp_count_sum, trlp_count_recv,          &
    142145                trlp_count_recv_sum, trlpt_count, trlpt_count_recv,            &
     
    150153    INTEGER ::  gp_outside_of_building(1:8)
    151154
     155    INTEGER, PARAMETER ::  maxtry = 40   ! for Rosenbrock method
     156
    152157    LOGICAL ::  dt_3d_reached, dt_3d_reached_l, prt_position
    153158
    154     REAL    ::  aa, arg, bb, cc, dd, delta_r, delta_v, dens_ratio, de_dt,      &
    155                 de_dt_min, de_dx_int, de_dx_int_l, de_dx_int_u, de_dy_int,     &
    156                 de_dy_int_l, de_dy_int_u, de_dz_int, de_dz_int_l, de_dz_int_u, &
    157                 diss_int, diss_int_l, diss_int_u, distance, dt_gap,            &
    158                 dt_particle, dt_particle_m, d_radius, d_sum, e_a, e_int,       &
    159                 e_int_l, e_int_u, e_mean_int, e_s, exp_arg, exp_term, fs_int,  &
    160                 gg, integral, lagr_timescale, lw_max, mean_r, new_r, p_int,    &
    161                 pt_int, pt_int_l, pt_int_u, q_int, q_int_l, q_int_u, ql_int,   &
    162                 ql_int_l, ql_int_u, random_gauss, sl_r3, sl_r4, t_int, u_int,  &
    163                 u_int_l, u_int_u,vv_int, v_int, v_int_l, v_int_u, w_int,       &
    164                 w_int_l, w_int_u, x, y
     159    REAL    ::  aa, afactor, arg, bb, cc, dd, ddenom, delta_r, delta_v, &
     160                dens_ratio, de_dt, de_dt_min, de_dx_int, de_dx_int_l, &
     161                de_dx_int_u, de_dy_int, de_dy_int_l, de_dy_int_u, de_dz_int, &
     162                de_dz_int_l, de_dz_int_u, diss_int, diss_int_l, diss_int_u, &
     163                distance, drdt, drdt_ini, drdt_m, dt_ros, dt_ros_last, &
     164                dt_ros_next, dt_ros_sum, dt_ros_sum_ini, d2rdt2, d2rdtdr, &
     165                dt_gap, dt_particle, dt_particle_m, d_sum, e_a, e_int, &
     166                e_int_l, e_int_u, e_mean_int, e_s, err_ros, errmax, exp_arg, &
     167                exp_term, fs_int, gg, g1, g2, g3, g4, integral, &
     168                lagr_timescale, lw_max, mean_r, new_r, p_int, pt_int, &
     169                pt_int_l, pt_int_u, q_int, q_int_l, q_int_u, ql_int, ql_int_l, &
     170                ql_int_u, random_gauss, r_ros, r_ros_ini, sigma, sl_r3, sl_r4, &
     171                t_int, u_int, u_int_l, u_int_u,vv_int, v_int, v_int_l, &
     172                v_int_u, w_int, w_int_l, w_int_u, x, y
     173!
     174!-- Parameters for Rosenbrock method
     175    REAL, PARAMETER ::  a21 = 2.0, a31 = 48.0/25.0, a32 = 6.0/25.0,        &
     176                        a2x = 1.0, a3x = 3.0/5.0, b1 = 19.0/9.0, b2 = 0.5, &
     177                        b3 = 25.0/108.0, b4 = 125.0/108.0, c21 = -8.0,     &
     178                        c31 = 372.0/25.0, c32 = 12.0/5.0,                  &
     179                        c41 = -112.0/125.0, c42 = -54.0/125.0,             &
     180                        c43 = -2.0/5.0, c1x = 0.5, c2x= -3.0/2.0,          &
     181                        c3x = 121.0/50.0, c4x = 29.0/250.0,                &
     182                        errcon = 0.1296, e1 = 17.0/54.0, e2 = 7.0/36.0,    &
     183                        e3 = 0.0, e4 = 125.0/108.0, gam = 0.5, grow = 1.5, &
     184                        pgrow = -0.25, pshrnk = -1.0/3.0, shrnk = 0.5
    165185
    166186    REAL, DIMENSION(1:30) ::  de_dxi, de_dyi, de_dzi, dissi, d_gp_pl, ei
     
    337357!
    338358!--       Change in radius by condensation/evaporation
    339 !--       ATTENTION: this is only an approximation for large radii
    340           arg = particles(n)%radius**2 + 2.0 * dt_3d *                     &
    341                         ( e_a / e_s - 1.0 ) /                              &
    342                         ( ( l_d_rv / t_int - 1.0 ) * l_v * rho_l / t_int / &
    343                           thermal_conductivity_l +                         &
    344                           rho_l * r_v * t_int / diff_coeff_l / e_s )
    345           IF ( arg < 1.0E-14 )  THEN
    346              new_r = 1.0E-7
     359          IF ( curvature_solution_effects .AND. particles(n)%radius < 1.0E-6 ) &
     360          THEN
     361!
     362!--          Curvature and solutions effects are included in growth equation.
     363!--          Change in Radius is calculated with 4th-order Rosenbrock method
     364!--          for stiff o.d.e's with monitoring local truncation error to adjust
     365!--          stepsize (see Numerical recipes in FORTRAN, 2nd edition, p. 731).
     366!--          For larger radii the simple analytic method (see ELSE) gives
     367!--          almost the same results.
     368!
     369!--          Surface tension after (Straka, 2009)
     370             sigma = 0.0761 - 0.00155 * ( t_int - 273.15 )
     371
     372             r_ros = particles(n)%radius
     373             dt_ros_sum  = 0.0      ! internal integrated time (s)
     374             internal_timestep_count = 0
     375
     376             ddenom  = 1.0 / ( rho_l * r_v * t_int / ( e_s * diff_coeff_l ) +  &
     377                               ( l_v / ( r_v * t_int ) - 1.0 ) *               &
     378                               rho_l * l_v / ( thermal_conductivity_l * t_int )&
     379                             )
     380             
     381             afactor = 2.0 * sigma / ( rho_l * r_v * t_int )
     382
     383             IF ( particles(n)%rvar3 == -9999999.9 )  THEN
     384!
     385!--             First particle timestep. Derivative has to be calculated.
     386                drdt_m  = ddenom / r_ros * ( e_a / e_s - 1.0 -    &
     387                                             afactor / r_ros +    &
     388                                             bfactor / r_ros**3 )
     389             ELSE
     390!
     391!--             Take value from last PALM timestep
     392                drdt_m = particles(n)%rvar3
     393             ENDIF
     394!
     395!--          Take internal timestep values from the end of last PALM timestep
     396             dt_ros_last = particles(n)%rvar1
     397             dt_ros_next = particles(n)%rvar2
     398!
     399!--          Internal timestep must not be larger than PALM timestep
     400             dt_ros = MIN( dt_ros_next, dt_3d )
     401!
     402!--          Integrate growth equation in time unless PALM timestep is reached
     403             DO WHILE ( dt_ros_sum < dt_3d )
     404
     405                internal_timestep_count = internal_timestep_count + 1
     406
     407!
     408!--             Derivative at starting value
     409                drdt = ddenom / r_ros * ( e_a / e_s - 1.0 - afactor / r_ros + &
     410                                          bfactor / r_ros**3 )
     411                drdt_ini       = drdt
     412                dt_ros_sum_ini = dt_ros_sum
     413                r_ros_ini      = r_ros
     414
     415!
     416!--             Calculate time derivative of dr/dt
     417                d2rdt2 = ( drdt - drdt_m ) / dt_ros_last
     418
     419!
     420!--             Calculate radial derivative of dr/dt
     421                d2rdtdr = ddenom * ( ( 1.0 - e_a/e_s ) / r_ros**2 + &
     422                                     2.0 * afactor / r_ros**3 -     &
     423                                     4.0 * bfactor / r_ros**5 )
     424!
     425!--             Adjust stepsize unless required accuracy is reached
     426                DO  jtry = 1, maxtry+1
     427
     428                   IF ( jtry == maxtry+1 )  THEN
     429                      message_string = 'maxtry > 40 in Rosenbrock method'
     430                      CALL message( 'advec_particles', 'PA0347', 2, 2, 0, 6, 0 )
     431                   ENDIF
     432
     433                   aa    = 1.0 / ( gam * dt_ros ) - d2rdtdr
     434                   g1    = ( drdt_ini + dt_ros * c1x * d2rdt2 ) / aa
     435                   r_ros = r_ros_ini + a21 * g1
     436                   drdt  = ddenom / r_ros * ( e_a / e_s - 1.0 - &
     437                                              afactor / r_ros + &
     438                                              bfactor / r_ros**3 )
     439
     440                   g2    = ( drdt + dt_ros * c2x * d2rdt2 + c21 * g1 / dt_ros )&
     441                           / aa
     442                   r_ros = r_ros_ini + a31 * g1 + a32 * g2
     443                   drdt  = ddenom / r_ros * ( e_a / e_s - 1.0 - &
     444                                              afactor / r_ros + &
     445                                              bfactor / r_ros**3 )
     446
     447                   g3    = ( drdt + dt_ros * c3x * d2rdt2 + &
     448                             ( c31 * g1 + c32 * g2 ) / dt_ros ) / aa
     449                   g4    = ( drdt + dt_ros * c4x * d2rdt2 + &
     450                             ( c41 * g1 + c42 * g2 + c43 * g3 ) / dt_ros ) / aa
     451                   r_ros = r_ros_ini + b1 * g1 + b2 * g2 + b3 * g3 + b4 * g4
     452
     453                   dt_ros_sum = dt_ros_sum_ini + dt_ros
     454
     455                   IF ( dt_ros_sum == dt_ros_sum_ini )  THEN
     456                      message_string = 'zero stepsize in Rosenbrock method'
     457                      CALL message( 'advec_particles', 'PA0348', 2, 2, 0, 6, 0 )
     458                   ENDIF
     459!
     460!--                Calculate error
     461                   err_ros = e1*g1 + e2*g2 + e3*g3 + e4*g4
     462                   errmax  = 0.0
     463                   errmax  = MAX( errmax, ABS( err_ros / r_ros_ini ) ) / eps_ros
     464!
     465!--                Leave loop if accuracy is sufficient, otherwise try again
     466!--                with a reduced stepsize
     467                   IF ( errmax <= 1.0 )  THEN
     468                      EXIT
     469                   ELSE
     470                      dt_ros = SIGN(                                           &
     471                                    MAX( ABS( 0.9 * dt_ros * errmax**pshrnk ), &
     472                                         shrnk * ABS( dt_ros ) ),              &
     473                                    dt_ros                                     &
     474                                   )
     475                   ENDIF
     476
     477                ENDDO  ! loop for stepsize adjustment
     478
     479!
     480!--             Calculate next internal timestep
     481                IF ( errmax > errcon )  THEN
     482                   dt_ros_next = 0.9 * dt_ros * errmax**pgrow
     483                ELSE
     484                   dt_ros_next = grow * dt_ros
     485                ENDIF
     486
     487!
     488!--             Estimated timestep is reduced if the PALM time step is exceeded
     489                dt_ros_last = dt_ros
     490                IF ( ( dt_ros_next + dt_ros_sum ) >= dt_3d )  THEN
     491                   dt_ros = dt_3d - dt_ros_sum
     492                ELSE
     493                   dt_ros = dt_ros_next
     494                ENDIF
     495
     496                drdt_m = drdt
     497
     498             ENDDO
     499!
     500!--          Store derivative and internal timestep values for next PALM step
     501             particles(n)%rvar1 = dt_ros_last
     502             particles(n)%rvar2 = dt_ros_next
     503             particles(n)%rvar3 = drdt_m
     504
     505             new_r = r_ros
     506!
     507!--          Radius should not fall below 1E-8 because Rosenbrock method may
     508!--          lead to errors otherwise
     509             new_r = MAX( new_r, 1.0E-8 )
     510
    347511          ELSE
    348              new_r = SQRT( arg )
     512!
     513!--          Approximation for large radii, where curvature and solution
     514!--          effects can be neglected
     515             arg = particles(n)%radius**2 + 2.0 * dt_3d *                     &
     516                           ( e_a / e_s - 1.0 ) /                              &
     517                           ( ( l_d_rv / t_int - 1.0 ) * l_v * rho_l / t_int / &
     518                             thermal_conductivity_l +                         &
     519                             rho_l * r_v * t_int / diff_coeff_l / e_s )
     520             IF ( arg < 1.0E-14 )  THEN
     521                new_r = 1.0E-7
     522             ELSE
     523                new_r = SQRT( arg )
     524             ENDIF
     525
    349526          ENDIF
    350527
    351528          delta_r = new_r - particles(n)%radius
    352 
    353 ! NOTE: this is the correct formula (indipendent of radius).
    354 !       nevertheless, it give wrong results for large timesteps
    355 !          d_radius =  1.0 / particles(n)%radius
    356 !          delta_r = d_radius * ( e_a / e_s - 1.0 - 3.3E-7 / t_int * d_radius + &
    357 !                                 b_cond * d_radius**3 ) /                      &
    358 !                    ( ( l_d_rv / t_int - 1.0 ) * l_v * rho_l / t_int /         &
    359 !                      thermal_conductivity_l +                                 &
    360 !                      rho_l * r_v * t_int / diff_coeff_l / e_s ) * dt_3d
    361 
    362 !          new_r = particles(n)%radius + delta_r
    363 !          IF ( new_r < 1.0E-7 )  new_r = 1.0E-7
    364529
    365530!
     
    389554             WRITE( message_string, * ) '#1 k=',k,' j=',j,' i=',i,   &
    390555                          ' e_s=',e_s, ' e_a=',e_a,' t_int=',t_int,  &
    391                           ' &d_radius=',d_radius,' delta_r=',delta_r,&
     556                          ' &delta_r=',delta_r,                      &
    392557                          ' particle_radius=',particles(n)%radius
    393558             CALL message( 'advec_particles', 'PA0144', 2, 2, -1, 6, 1 )
     
    19652130!--             [-5.0*sigma, 5.0*sigma] in order to prevent the SGS velocities
    19662131!--             from becoming unrealistically large.
    1967                 particles(n)%speed_x_sgs = SQRT( 2.0 * sgs_wfu_part * e_int ) *&
    1968                                            ( random_gauss( iran_part, 5.0 )    &
     2132                particles(n)%rvar1 = SQRT( 2.0 * sgs_wfu_part * e_int ) *   &
     2133                                           ( random_gauss( iran_part, 5.0 ) &
    19692134                                             - 1.0 )
    1970                 particles(n)%speed_y_sgs = SQRT( 2.0 * sgs_wfv_part * e_int ) *&
    1971                                            ( random_gauss( iran_part, 5.0 )    &
     2135                particles(n)%rvar2 = SQRT( 2.0 * sgs_wfv_part * e_int ) *   &
     2136                                           ( random_gauss( iran_part, 5.0 ) &
    19722137                                             - 1.0 )
    1973                 particles(n)%speed_z_sgs = SQRT( 2.0 * sgs_wfw_part * e_int ) *&
    1974                                            ( random_gauss( iran_part, 5.0 )    &
     2138                particles(n)%rvar3 = SQRT( 2.0 * sgs_wfw_part * e_int ) *   &
     2139                                           ( random_gauss( iran_part, 5.0 ) &
    19752140                                             - 1.0 )
    19762141
     
    20032168                ENDIF
    20042169
    2005                 particles(n)%speed_x_sgs = particles(n)%speed_x_sgs -          &
    2006                        fs_int * c_0 * diss_int * particles(n)%speed_x_sgs *    &
     2170                particles(n)%rvar1 = particles(n)%rvar1 -                      &
     2171                       fs_int * c_0 * diss_int * particles(n)%rvar1 *          &
    20072172                       dt_particle / ( 4.0 * sgs_wfu_part * e_int ) +          &
    20082173                       ( 2.0 * sgs_wfu_part * de_dt *                          &
    2009                                particles(n)%speed_x_sgs /                      &
     2174                               particles(n)%rvar1 /                            &
    20102175                         ( 2.0 * sgs_wfu_part * e_int ) + de_dx_int            &
    20112176                       ) * dt_particle / 2.0                        +          &
     
    20142179                       SQRT( dt_particle )
    20152180
    2016                 particles(n)%speed_y_sgs = particles(n)%speed_y_sgs -          &
    2017                        fs_int * c_0 * diss_int * particles(n)%speed_y_sgs *    &
     2181                particles(n)%rvar2 = particles(n)%rvar2 -                      &
     2182                       fs_int * c_0 * diss_int * particles(n)%rvar2 *          &
    20182183                       dt_particle / ( 4.0 * sgs_wfv_part * e_int ) +          &
    20192184                       ( 2.0 * sgs_wfv_part * de_dt *                          &
    2020                                particles(n)%speed_y_sgs /                      &
     2185                               particles(n)%rvar2 /                            &
    20212186                         ( 2.0 * sgs_wfv_part * e_int ) + de_dy_int            &
    20222187                       ) * dt_particle / 2.0                        +          &
     
    20252190                       SQRT( dt_particle )
    20262191
    2027                 particles(n)%speed_z_sgs = particles(n)%speed_z_sgs -          &
    2028                        fs_int * c_0 * diss_int * particles(n)%speed_z_sgs *    &
     2192                particles(n)%rvar3 = particles(n)%rvar3 -          &
     2193                       fs_int * c_0 * diss_int * particles(n)%rvar3 *    &
    20292194                       dt_particle / ( 4.0 * sgs_wfw_part * e_int ) +          &
    20302195                       ( 2.0 * sgs_wfw_part * de_dt *                          &
    2031                                particles(n)%speed_z_sgs /                      &
     2196                               particles(n)%rvar3 /                      &
    20322197                         ( 2.0 * sgs_wfw_part * e_int ) + de_dz_int            &
    20332198                       ) * dt_particle / 2.0                        +          &
     
    20382203             ENDIF
    20392204
    2040              u_int = u_int + particles(n)%speed_x_sgs
    2041              v_int = v_int + particles(n)%speed_y_sgs
    2042              w_int = w_int + particles(n)%speed_z_sgs
     2205             u_int = u_int + particles(n)%rvar1
     2206             v_int = v_int + particles(n)%rvar2
     2207             w_int = w_int + particles(n)%rvar3
    20432208
    20442209!
     
    33783543                particles(n)%speed_z = -particles(n)%speed_z
    33793544                IF ( use_sgs_for_particles  .AND. &
    3380                      particles(n)%speed_z_sgs > 0.0 )  THEN
    3381                    particles(n)%speed_z_sgs = -particles(n)%speed_z_sgs
     3545                     particles(n)%rvar3 > 0.0 )  THEN
     3546                   particles(n)%rvar3 = -particles(n)%rvar3
    33823547                ENDIF
    33833548                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
     
    34033568                particles(n)%speed_z = -particles(n)%speed_z
    34043569                IF ( use_sgs_for_particles  .AND. &
    3405                      particles(n)%speed_z_sgs < 0.0 )  THEN
    3406                    particles(n)%speed_z_sgs = -particles(n)%speed_z_sgs
     3570                     particles(n)%rvar3 < 0.0 )  THEN
     3571                   particles(n)%rvar3 = -particles(n)%rvar3
    34073572                ENDIF
    34083573                IF ( use_particle_tails  .AND.  nn /= 0 )  THEN
     
    41874352
    41884353          particles_temp => part_1
    4189           part_1 = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
    4190                                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
    4191                                   0.0, 0, 0, 0, 0 )
     4354!          part_1 = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
     4355!                                  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
     4356!                                  0.0, 0, 0, 0, 0 )
    41924357
    41934358       CASE ( 1 )
    41944359
    41954360          particles_temp => part_2
    4196           part_2 = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
    4197                                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
    4198                                   0.0, 0, 0, 0, 0 )
     4361!          part_2 = particle_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
     4362!                                  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
     4363!                                  0.0, 0, 0, 0, 0 )
    41994364
    42004365    END SELECT
Note: See TracChangeset for help on using the changeset viewer.